package com.ctshk.rpc.localfun.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.localfun.dto.*;
import com.ctshk.rpc.localfun.entity.*;
import com.ctshk.rpc.localfun.enums.ProductCenterEnum;
import com.ctshk.rpc.localfun.mapper.*;
import com.ctshk.rpc.localfun.req.*;
import com.ctshk.rpc.localfun.req.cache.LocalFunProductCacheOpsReq;
import com.ctshk.rpc.localfun.service.ILocalFunAppProductService;
import com.ctshk.rpc.localfun.service.ILocalFunCostPriceService;
import com.ctshk.rpc.localfun.service.ILocalFunProductService;
import com.ctshk.rpc.localfun.util.NumberUtil;
import com.ctshk.rpc.system.dto.SysAgentQueryListDTO;
import com.ctshk.rpc.system.dto.SysDepartmentDTO;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.req.SysAgentQueryListReq;
import com.ctshk.rpc.system.service.ISysAgentService;
import com.ctshk.rpc.system.service.ISysDepartmentService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import com.ctshk.rpc.system.service.ISysUserService;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description  当地玩乐-产品中心
 * @Author wansi <gaylen15527491065@yeah.net>
 * @Date 2021/3/24
 */
@Slf4j
@DubboService
public class LocalFunProductServiceImpl extends ServiceImpl<LocalFunProductMapper, LocalFunProduct> implements ILocalFunProductService {

    @Autowired
    private LocalFunProductMapper localFunProductMapper;
    @Autowired
    private LocalFunProductSaleStrategyMapper localFunProductSaleStrategyMapper;
    @Autowired
    private LocalFunProductSaleStrategyVaildDateMapper localFunProductSaleStrategyVaildDateMapper;
    @Autowired
    private LocalFunProductChannelOfflineMapper localFunProductChannelOfflineMapper;
    @Autowired
    private LocalFunProductChannelOfflineSelfCustomMapper localFunProductChannelOfflineSelfCustomMapper;
    @Autowired
    private LocalFunProductChannelOfflineAgentCustomMapper localFunProductChannelOfflineAgentCustomMapper;
    @Autowired
    private LocalFunProductChannelOnlineSelfPlatformMapper channelOnlineSelfPlatformMapper;
    @Autowired
    private LocalFunProductChannelOnlineThirdPlatformMapper channelOnlineThirdPlatformMapper;
    @Autowired
    private LocalFunProductCostStrategyMapper localFunProductCostStrategyMapper;
    @Autowired
    private LocalFunProductCostStrategySpecStockMapper localFunProductCostStrategySpecStockMapper;
    @Autowired
    private LocalFunProductCostStrategySpecAttrMapper costStrategySpecAttrMapper;
    @Autowired
    private LocalFunProductTicketMapper localFunProductTicketMapper;
    @DubboReference
    private ISysUserService iSysUserService;
    @DubboReference
    private ISysDepartmentService departmentService;
    @Autowired
    private LocalFunProductSaleRecordMapper localFunProductSaleRecordMapper;
    @Autowired
    private LocalFunProductCostStrategyVaildDateMapper costStrategyVaildDateMapper;
    @DubboReference
    private ISysDepartmentService iSysDepartmentService;
    @DubboReference
    private ILocalFunCostPriceService iLocalFunCostPriceService;
    @DubboReference
    private ISysAgentService sysAgentService;
    private static final String IS_LIMIT = "无限制";
    @DubboReference
    private ISysPermissionService sysPermissionService;
    @Autowired
    private LocalFunProductSaleRecordMapper saleRecordMapper;
    @DubboReference
    private ILocalFunAppProductService iLocalFunAppProductService;

    @Override
    public PageResponse<LocalFunProductListDTO> list(LocalFunProductListReq req, TokenUser currentUser) {
        IPage<LocalFunProduct> iPage = new Page<>(req.getPageNo(), req.getPageSize());
        //判断是否有权限查看.
        List<Long> data = Lists.newArrayListWithCapacity(5);
        if (!GlobalConstants.Role.isAdmin(currentUser.getUsername())) {
            if (req.getMenuId() == null) {
                throw new BusinessException(SystemError.SYSTEM_2106);
            }
            Result<List<Long>> permissionResult = sysPermissionService.queryPermission(req.getMenuId(), currentUser.getId());
            if (!permissionResult.isSuccess()) {
                SystemError result = SystemError.getDefined(permissionResult.getCode());
                throw new BusinessException(result);
            }
            data.addAll(permissionResult.getData());
        }
        //分页查询结果集
        Page<LocalFunProduct> insuranceIPage = baseMapper.queryProductList(req,data,iPage);
        if (CollectionUtils.isNotEmpty(insuranceIPage.getRecords())) {
            List<LocalFunProductListDTO> scenicProductListDTOList = EntityUtil.copyList(iPage.getRecords(),LocalFunProductListDTO.class);
            try {
                scenicProductListDTOList.forEach(entity->{
                    if (entity.getChargeUserId() != null) {
                        UserDTO userDTO = null;
                        try {
                            userDTO = iSysUserService.loadUserByParam(entity.getChargeUserId(), 1);
                            entity.setChargeUser(userDTO.getCreateDept());
                        } catch (Exception e) {
                            Result.failed(SystemError.SYS_500);
                        }
                    }
                });
            } catch (Exception e) {
                log.error("设置负责人名称/部门失败：{}",e.getMessage());
            }
            setDic(scenicProductListDTOList);
            return new PageResponse<>(scenicProductListDTOList, insuranceIPage.getCurrent() == 1,
                    insuranceIPage.getTotal() <= (insuranceIPage.getCurrent() * insuranceIPage.getSize()), iPage.getTotal(), insuranceIPage.getCurrent(), iPage.getSize());
        }
        return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    /**
     * 映射字符串
     * @param scenicProductListDTOList
     */
    private void setDic(List<LocalFunProductListDTO> scenicProductListDTOList) {
        scenicProductListDTOList.forEach(entity->{
            if(entity.getIsRecommend() == null){
                entity.setIsRecommendDesc("-");
            }else {
                entity.setIsRecommendDesc(1 == entity.getIsRecommend() ? "推薦中":"無");
            }
            entity.setStatusDesc(1 == entity.getStatus() ? "已上架":"未上架");
        });
    }

    @Override
    public Result modifyRecommendStatus(LocalFunProductModifyRecommendStatusReq localFunProductModifyRecommendStatusReq, TokenUser currentUser) {
        LocalFunProduct localFunProduct = baseMapper.selectById(localFunProductModifyRecommendStatusReq.getId());
        if(localFunProduct == null){
            throw new BusinessException(SystemError.MAINDATA_4021);
        }
        //设置推荐状态 0 無,推薦中 1
        localFunProduct.setIsRecommend(localFunProductModifyRecommendStatusReq.getIsRecommend());
        localFunProduct.setGmtModified(LocalDateTime.now());
        if(NumberConstant.ONE.getValue().equals(baseMapper.updateById(localFunProduct))){
            //刷新缓存
            try {
                CompletableFuture.runAsync(() -> {
                    LocalFunProductCacheOpsReq req1 = new LocalFunProductCacheOpsReq();
                    req1.setIds(Lists.newArrayList(Long.valueOf(localFunProductModifyRecommendStatusReq.getId())));
                    iLocalFunAppProductService.cacheUpdate(req1);
                });
                log.info("[当地玩乐-上架设置] 同步缓存成功");
            } catch (Exception e) {
                log.info("[当地玩乐-上架设置] 同步缓存失败：{}",e.getMessage());
            }
            return Result.success(localFunProduct.getId());
        }
        return Result.failed(new BusinessException(SystemError.MAINDATA_4021));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result putAway(LocalFunProductBatchSaleStrategyReq req, TokenUser currentUser) {
        //获取当前用户ID
        Long userId = currentUser == null ? null : currentUser.getId();
        //数据准备
        List<Long> funProductIdList = req.getLocalFunProductIdList();
        List<LocalFunProductSaleStrategyReq> strategyList = req.getStrategyList();

        //數據校驗
        Result result = checkDataBeforePutAway(req, funProductIdList, strategyList);
        if (result != null) return result;

        //遍历配置每个产品的增幅策略
        for (Long productId : funProductIdList) {

            //删除历史策略数据
            deleteHistoryStrategyData(productId);

            for (LocalFunProductSaleStrategyReq localFunProductSaleStrategyReq : strategyList) {
                //1.新增产品增幅策略
                Long id = addSaleStrategy(userId, productId, localFunProductSaleStrategyReq);

                //2.设置产品增幅策略有效期
                addSaleStrategyValidDate(productId, localFunProductSaleStrategyReq, id);

                //3.设置渠道加幅
                addChannelSale(id,localFunProductSaleStrategyReq,productId,userId);
            }
            LocalFunProduct localFunProduct = localFunProductMapper.selectById(productId);
            //已上架
            localFunProduct.setStatus(1);
            localFunProductMapper.updateById(localFunProduct);
        }

        //刷新缓存
        try {
            CompletableFuture.runAsync(() -> {
                LocalFunProductCacheOpsReq req1 = new LocalFunProductCacheOpsReq();
                req1.setIds(funProductIdList);
                iLocalFunAppProductService.cacheUpdate(req1);
            });
            log.info("[当地玩乐-上架设置] 同步缓存成功");
        } catch (Exception e) {
            log.info("[当地玩乐-上架设置] 同步缓存失败：{}",e.getMessage());
        }
        return Result.success();
    }

    /**
     * 删除历史数据
     * @param productId
     */
    private void deleteHistoryStrategyData(Long productId) {
        QueryWrapper<LocalFunProductSaleStrategy> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(LocalFunProductSaleStrategy::getProductId,productId);
        List<LocalFunProductSaleStrategy> strategies = localFunProductSaleStrategyMapper.selectList(queryWrapper);

        if(CollectionUtils.isNotEmpty(strategies)){
            strategies.forEach(entity->{
                //删除策略
                localFunProductSaleStrategyMapper.deleteById(entity.getId());
                //删除有效期
                QueryWrapper<LocalFunProductSaleStrategyVaildDate> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.lambda().eq(LocalFunProductSaleStrategyVaildDate::getStrategyId,entity.getId());
                localFunProductSaleStrategyVaildDateMapper.delete(queryWrapper1);

                //删除权限
                QueryWrapper<LocalFunProductChannelOffline> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.lambda().eq(LocalFunProductChannelOffline::getStrategyId,entity.getId());
                List<LocalFunProductChannelOffline> channelOfflines = localFunProductChannelOfflineMapper.selectList(queryWrapper2);

                if(CollectionUtils.isNotEmpty(channelOfflines)){
                    channelOfflines.forEach(en->{
                        //删除权限
                        localFunProductChannelOfflineMapper.deleteById(en.getId());
                        //删除线下自营
                        if(en.getChannelType() ==1){
                            QueryWrapper<LocalFunProductChannelOfflineSelfCustom> queryWrapper3 = new QueryWrapper<>();
                            queryWrapper3.lambda().eq(LocalFunProductChannelOfflineSelfCustom::getOfflineId,en.getId());
                            localFunProductChannelOfflineSelfCustomMapper.delete(queryWrapper3);
                        }
                        //删除代理商
                        else {
                            QueryWrapper<LocalFunProductChannelOfflineAgentCustom> queryWrapper3 = new QueryWrapper<>();
                            queryWrapper3.lambda().eq(LocalFunProductChannelOfflineAgentCustom::getOfflineId,en.getId());
                            localFunProductChannelOfflineAgentCustomMapper.delete(queryWrapper3);
                        }
                    });
                }

                //官方平台
                QueryWrapper<LocalFunProductChannelOnlineSelfPlatform> queryWrapper4 = new QueryWrapper<>();
                queryWrapper4.lambda().eq(LocalFunProductChannelOnlineSelfPlatform::getStrategyId,entity.getId());
                channelOnlineSelfPlatformMapper.delete(queryWrapper4);
                //第三方平台
                QueryWrapper<LocalFunProductChannelOnlineThirdPlatform> queryWrapper5 = new QueryWrapper<>();
                queryWrapper5.lambda().eq(LocalFunProductChannelOnlineThirdPlatform::getStrategyId,entity.getId());
                channelOnlineThirdPlatformMapper.delete(queryWrapper5);
            });
        }
    }


    /**
     * 數據校驗
     * @param req
     * @param funProductIdList
     * @param strategyList
     * @return
     */
    private Result checkDataBeforePutAway(LocalFunProductBatchSaleStrategyReq req, List<Long> funProductIdList, List<LocalFunProductSaleStrategyReq> strategyList) {
        //增幅策略空数据校验
        if (checkStrategyEmpty(funProductIdList,strategyList)) {
            return Result.failed(SystemError.LOCAL_FUN_18002);
        }

        //校驗有效期和加幅策略個數
        if(checkStrategyCandidateCount(strategyList)){
            return Result.failed(SystemError.LOCAL_FUN_18005);
        }

        //校验当地玩乐成本有效期是否重复
        if(duplicateDateForUseDate(req)){
            return Result.failed(SystemError.LOCAL_FUN_18003);
        }
        return null;
    }

    /**
     * 校驗有效期和加幅策略個數
     * @param strategyList
     * @return
     */
    private boolean checkStrategyCandidateCount(List<LocalFunProductSaleStrategyReq> strategyList) {
        if(strategyList.size() > 5){
            return true;
        }

        for(LocalFunProductSaleStrategyReq strategy : strategyList){
            List<LocalFunTimeDTO> time = strategy.getTime();
            if(time != null && time.size() > 5){
                return true;
            }
        }
        return false;
    }


    /**
     * 校验当地玩乐成本有效期是否重复
     * 思路：1.收集开始日期到结束日期的所有结果集合
     * 2.将日期去重和日期集合总数对比，不相等代表存在重复的有效日期
     * @param req
     * @return
     */
    private boolean duplicateDateForUseDate(LocalFunProductBatchSaleStrategyReq req) {
        List<LocalFunProductSaleStrategyReq> strategyList = req.getStrategyList();
        Set<LocalDate> localDateSet = Sets.newHashSet();
        int localDateSize = 0;
        for (LocalFunProductSaleStrategyReq airProductCostDataReq : strategyList) {
            List<LocalFunTimeDTO> timeDataList = airProductCostDataReq.getTime();
            if(CollectionUtils.isEmpty(timeDataList)){
                return false;
            }
            for (LocalFunTimeDTO airProductCostDateData : timeDataList) {
                LocalDate dateBegin = airProductCostDateData.getBeginTime();
                LocalDate dateEnd = airProductCostDateData.getEndTime();
                //获取开始日期-结束日期的集合
                List<LocalDate> dates = Stream.iterate(dateBegin, date -> date.plusDays(1))
                        .limit(ChronoUnit.DAYS.between(dateBegin, dateEnd))
                        .collect(Collectors.toList());
                dates.add(dateEnd);
                localDateSet.addAll(dates);
                localDateSize += dates.size();
            }
        }
        return localDateSet.size() != localDateSize;
    }

    @Override
    public Result<List<LocalFunProductSaleStrategyDTO>> LocalFunProductEditDetai(LocalFunProductEditReq localFunProductEditReq) {
        List<LocalFunProductSaleStrategyDTO> saleStrategyDTOS = new ArrayList<>();
        QueryWrapper<LocalFunProductSaleStrategy> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", localFunProductEditReq.getId());
        List<LocalFunProductSaleStrategy> strategies = localFunProductSaleStrategyMapper.selectList(queryWrapper);

        if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(strategies)) {
            for (LocalFunProductSaleStrategy strategy : strategies) {
                LocalFunProductSaleStrategyDTO scenicProductSaleStrategyDTO = new LocalFunProductSaleStrategyDTO();
                //1.策略名称
                scenicProductSaleStrategyDTO.setName(strategy.getName());
                //2.设置策略有效期
                setValidDate(strategy, scenicProductSaleStrategyDTO);
                scenicProductSaleStrategyDTO.setIncreaseStrategyId(strategy.getId());

                //3.设置加幅策略
                setChannelSaleStrategy(strategy,saleStrategyDTOS,scenicProductSaleStrategyDTO);
            }
        }
        return Result.success(saleStrategyDTOS);
    }

    private void setChannelSaleStrategy(LocalFunProductSaleStrategy strategy, List<LocalFunProductSaleStrategyDTO> saleStrategyDTOS, LocalFunProductSaleStrategyDTO scenicProductSaleStrategyDTO) {
        ChannelSaleDTO channelSaleDTO = new ChannelSaleDTO();

        LocalFunProductOfflineChannelDTO scenicProductOfflineChannelDTO = new LocalFunProductOfflineChannelDTO();
        //自营渠道
        QueryWrapper<LocalFunProductChannelOffline> offlineQueryWrapper = new QueryWrapper<>();
        offlineQueryWrapper.eq("product_id", strategy.getProductId());
        offlineQueryWrapper.eq("strategy_id", strategy.getId());
        List<LocalFunProductChannelOffline> channelOfflines = localFunProductChannelOfflineMapper.selectList(offlineQueryWrapper);

        if(CollectionUtils.isNotEmpty(channelOfflines)){

            for(LocalFunProductChannelOffline channelOffline : channelOfflines){
                if (channelOffline.getChannelType() == 1) {
                    if (channelOffline.getVisableType() == 1) {
                        scenicProductOfflineChannelDTO.setVisableType(1);
                        scenicProductOfflineChannelDTO.setOfflineSelfId(channelOffline.getId());
                    }
                    else if (channelOffline.getVisableType() == 2) {
                        QueryWrapper<LocalFunProductChannelOfflineSelfCustom> selfCustomQueryWrapper = new QueryWrapper<>();
                        selfCustomQueryWrapper.eq("product_id",strategy.getProductId());
                        selfCustomQueryWrapper.eq("offline_id",channelOffline.getId());
                        LocalFunProductChannelOfflineSelfCustom selfCustom = localFunProductChannelOfflineSelfCustomMapper.selectOne(selfCustomQueryWrapper);
                        if(selfCustom != null){
                            scenicProductOfflineChannelDTO = EntityUtil.copy(selfCustom, LocalFunProductOfflineChannelDTO.class);
                            scenicProductOfflineChannelDTO.setVisableType(channelOffline.getVisableType());
                        }
                    } else if(channelOffline.getVisableType() == 3){
                        scenicProductOfflineChannelDTO.setVisableType(3);
                        scenicProductOfflineChannelDTO.setOfflineSelfId(channelOffline.getId());
                        List<LocalFunProductChannelOfflineSelfCustomDTO> scenicProductChannelOfflineSelfCustomDTOList = new ArrayList<>();
                        QueryWrapper<LocalFunProductChannelOfflineSelfCustom> selfCustomQueryWrapper = new QueryWrapper<>();
                        selfCustomQueryWrapper.eq("product_id",strategy.getProductId());
                        selfCustomQueryWrapper.eq("offline_id",channelOffline.getId());
                        selfCustomQueryWrapper.eq("is_deleted",0);
                        List<LocalFunProductChannelOfflineSelfCustom> selfCustoms = localFunProductChannelOfflineSelfCustomMapper.selectList(selfCustomQueryWrapper);
                        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(selfCustoms)){
                            for(LocalFunProductChannelOfflineSelfCustom selfCustom : selfCustoms){
                                LocalFunProductChannelOfflineSelfCustomDTO scenicProductChannelOfflineSelfCustomDTO = EntityUtil.copy(selfCustom, LocalFunProductChannelOfflineSelfCustomDTO.class);
                                scenicProductChannelOfflineSelfCustomDTOList.add(scenicProductChannelOfflineSelfCustomDTO);
                                scenicProductOfflineChannelDTO.setScenicProductChannelOfflineSelfCustomDTOList(scenicProductChannelOfflineSelfCustomDTOList);
                            }
                        }
                    }
                    channelSaleDTO.setScenicProductOfflineChannelDTO(scenicProductOfflineChannelDTO);
                }else if(channelOffline.getChannelType() == 2){
                    //代理商
                    LocalFunProductAgentDTO scenicProductAgentDTO = new LocalFunProductAgentDTO();
                    if (channelOffline.getVisableType() == 1) {
                        scenicProductAgentDTO.setVisableType(1);
                        scenicProductAgentDTO.setOfflineAgentId(channelOffline.getId());
                    }
                    else if (channelOffline.getVisableType() == 2) {
                        QueryWrapper<LocalFunProductChannelOfflineAgentCustom> customQueryWrapper = new QueryWrapper<>();
                        customQueryWrapper.eq("product_id",strategy.getProductId());
                        customQueryWrapper.eq("offline_id",channelOffline.getId());
                        customQueryWrapper.eq("is_deleted",0);
                        LocalFunProductChannelOfflineAgentCustom agentCustom = localFunProductChannelOfflineAgentCustomMapper.selectOne(customQueryWrapper);
                        if(null != agentCustom){
                            scenicProductAgentDTO = EntityUtil.copy(agentCustom, LocalFunProductAgentDTO.class);
                            scenicProductAgentDTO.setVisableType(channelOffline.getChannelType());
                        }
                    }else if(channelOffline.getVisableType() == 3){
                        scenicProductAgentDTO.setVisableType(3);
                        scenicProductAgentDTO.setOfflineAgentId(channelOffline.getId());
                        List<LocalFunProductChannelOfflineAgentCustomDTO> scenicProductChannelOfflineAgentCustomDTOList = new ArrayList<>();
                        QueryWrapper<LocalFunProductChannelOfflineAgentCustom> customQueryWrapper = new QueryWrapper<>();
                        customQueryWrapper.eq("product_id",strategy.getProductId());
                        customQueryWrapper.eq("offline_id",channelOffline.getId());
                        customQueryWrapper.eq("is_deleted",0);
                        List<LocalFunProductChannelOfflineAgentCustom> agentCustomList = localFunProductChannelOfflineAgentCustomMapper.selectList(customQueryWrapper);
                        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(agentCustomList)){
                            for(LocalFunProductChannelOfflineAgentCustom agentCustom : agentCustomList){
                                LocalFunProductChannelOfflineAgentCustomDTO agentCustomDTO = EntityUtil.copy(agentCustom, LocalFunProductChannelOfflineAgentCustomDTO.class);
                                agentCustomDTO.setVisableType("3");
                                scenicProductChannelOfflineAgentCustomDTOList.add(agentCustomDTO);
                            }
                            scenicProductAgentDTO.setScenicProductChannelOfflineAgentCustomDTOList(scenicProductChannelOfflineAgentCustomDTOList);
                        }
                    }
                    channelSaleDTO.setScenicProductAgentDTO(scenicProductAgentDTO);
                }
            }
        }


        //线上官方平台
        List<LocalFunProductChannelOnlineSelfPlatformDTO> selfPlatformDTOList = new ArrayList<>();
        QueryWrapper<LocalFunProductChannelOnlineSelfPlatform> platformQueryWrapper = new QueryWrapper<>();
        platformQueryWrapper.eq("is_deleted",0);
        platformQueryWrapper.eq("product_id",strategy.getProductId());
        List<LocalFunProductChannelOnlineSelfPlatform> selfPlatformList = channelOnlineSelfPlatformMapper.selectList(platformQueryWrapper);
        if(CollectionUtils.isNotEmpty(selfPlatformList)){
            for(LocalFunProductChannelOnlineSelfPlatform selfPlatform : selfPlatformList){
                LocalFunProductChannelOnlineSelfPlatformDTO selfPlatformDTO = EntityUtil.copy(selfPlatform, LocalFunProductChannelOnlineSelfPlatformDTO.class);
                selfPlatformDTOList.add(selfPlatformDTO);
            }
            channelSaleDTO.setScenicProductChannelOnlineSelfPlatformDTOList(selfPlatformDTOList);
        }
        //第三方平台
        List<LocalFunProductChannelOnlineThirdPlatformDTO> scenicProductChannelOnlineThirdPlatformDTOList = new ArrayList<>();
        QueryWrapper<LocalFunProductChannelOnlineThirdPlatform> scenicProductChannelOnlineThirdPlatformQueryWrapper = new QueryWrapper();
        scenicProductChannelOnlineThirdPlatformQueryWrapper.eq("product_id",strategy.getProductId());
        List<LocalFunProductChannelOnlineThirdPlatform> platforms = channelOnlineThirdPlatformMapper.selectList(scenicProductChannelOnlineThirdPlatformQueryWrapper);
        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(platforms)){
            for(LocalFunProductChannelOnlineThirdPlatform selfPlatform : platforms){
                LocalFunProductChannelOnlineThirdPlatformDTO scenicProductChannelOnlineThirdPlatformDTO = EntityUtil.copy(selfPlatform, LocalFunProductChannelOnlineThirdPlatformDTO.class);
                scenicProductChannelOnlineThirdPlatformDTOList.add(scenicProductChannelOnlineThirdPlatformDTO);
            }
            channelSaleDTO.setScenicProductChannelOnlineThirdPlatformDTOList(scenicProductChannelOnlineThirdPlatformDTOList);
        }
        scenicProductSaleStrategyDTO.setChannelSaleDTO(channelSaleDTO);
        saleStrategyDTOS.add(scenicProductSaleStrategyDTO);
    }


    /**
     * 设置策略有效期
     * @param strategy
     * @param scenicProductSaleStrategyDTO
     */
    private void setValidDate(LocalFunProductSaleStrategy strategy, LocalFunProductSaleStrategyDTO scenicProductSaleStrategyDTO) {
        QueryWrapper<LocalFunProductSaleStrategyVaildDate> vaildDateQueryWrapper = new QueryWrapper<>();
        vaildDateQueryWrapper.eq("strategy_id", strategy.getId());
        List<LocalFunProductSaleStrategyVaildDate> list = localFunProductSaleStrategyVaildDateMapper.selectList(vaildDateQueryWrapper);
        List<LocalFunTimeDTO> timeDTOList = new ArrayList<>();
        if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(list)) {
            for (LocalFunProductSaleStrategyVaildDate vaildDate : list) {
                LocalFunTimeDTO scenicTimeDTO = new LocalFunTimeDTO();
                scenicTimeDTO.setBeginTime(vaildDate.getTimeBegin());
                scenicTimeDTO.setEndTime(vaildDate.getTimeEnd());
                scenicTimeDTO.setTimeId(vaildDate.getId());
                timeDTOList.add(scenicTimeDTO);
            }
        }
        scenicProductSaleStrategyDTO.setTime(timeDTOList);
    }

    @Override
    public Result<LocalFunStockDetailDTO> stockDetail(LocalFunProductStockDetailReq req, TokenUser currentUser) {
        QueryWrapper<LocalFunProductCostStrategySpecStock> wrapper=new QueryWrapper<>();
        //成本策略ID
        Optional.ofNullable(req.getStrategyId()).map(strategyId ->
                wrapper.lambda().eq(LocalFunProductCostStrategySpecStock::getId, strategyId));
        //产品ID
        Optional.ofNullable(req.getProductId()).map(productId->
                wrapper.lambda().eq(LocalFunProductCostStrategySpecStock::getProductId,productId));
        LocalFunProductCostStrategySpecStock s= localFunProductCostStrategySpecStockMapper.selectOne(wrapper);
        LocalFunStockDetailDTO dto=EntityUtil.copy(s,LocalFunStockDetailDTO.class);


        return Result.success(dto);
    }

    /**
     * 线下渠道展示列表 = 指定部門/人員 + 代理商
     * 线上渠道展示列表 = 官方平台 + 第三方平台
     * @param localFunProductReq
     * @return
     * @throws ParseException
     */
    @Override
    public Result<LocalFunProductDetailDTO> LocalFunProductDetail(LocalFunProductReq localFunProductReq) throws ParseException {
        //日历渠道加幅策略
        LocalFunProductDetailDTO scenicProductDetailDTO = new LocalFunProductDetailDTO();
        LocalFunProduct scenicProduct = localFunProductMapper.selectById(localFunProductReq.getProductId());

        //1.封装产品基本信息
        warpperProductBaseInfo(scenicProductDetailDTO, scenicProduct);

        //2.日期对应加幅策略结果集
        scenicProductDetailDTO.setVaildDateDTOList(composeChannelStrategyByDate(scenicProductDetailDTO,scenicProduct,localFunProductReq));

        return Result.success(scenicProductDetailDTO);
    }

    /**
     * 封装有效期对应的渠道加幅策略信息
     * @param scenicProductDetailDTO
     * @param scenicProduct
     * @param localFunProductReq
     * @return
     */
    private List<VaildDateDTO> composeChannelStrategyByDate(LocalFunProductDetailDTO scenicProductDetailDTO, LocalFunProduct scenicProduct, LocalFunProductReq localFunProductReq) throws ParseException {
        List<OfflineCanalListDTO> offlineCanalListDTOList = Lists.newArrayListWithExpectedSize(10);
        List<OnlineSelfListDTO> onlineSelfListDTOList = Lists.newArrayListWithExpectedSize(10);
        List<VaildDateDTO> validDateDTOList = Lists.newArrayListWithExpectedSize(10);

        QueryWrapper<LocalFunProductSaleStrategy> wrapper=new QueryWrapper<>();
        wrapper.eq("product_id",localFunProductReq.getProductId());
        wrapper.eq("is_deleted",0);
        List<LocalFunProductSaleStrategy> list = localFunProductSaleStrategyMapper.selectList(wrapper);
        if(CollectionUtils.isEmpty(list)){
            return validDateDTOList;
        }

        for(LocalFunProductSaleStrategy scenicProductSaleStrategy : list){
            QueryWrapper<LocalFunProductChannelOffline> offlineQueryWrapper = new QueryWrapper<>();
            offlineQueryWrapper.eq("is_deleted",0);
            offlineQueryWrapper.eq("strategy_id",scenicProductSaleStrategy.getId());
            offlineQueryWrapper.in("visable_type",new Integer[]{2,3});
            List<LocalFunProductChannelOffline> scenicProductChannelOfflineList = localFunProductChannelOfflineMapper.selectList(offlineQueryWrapper);

            //线下渠道展示列表 = 指定部門/人員 + 代理商
            if(CollectionUtils.isNotEmpty(scenicProductChannelOfflineList)){
                LocalFunProductChannelOffline channelOffLine1 = scenicProductChannelOfflineList.stream().filter(entity->entity.getChannelType()==1).findFirst().orElse(null);
                LocalFunProductChannelOffline channelOffLine2 = scenicProductChannelOfflineList.stream().filter(entity->entity.getChannelType()==2).findFirst().orElse(null);

                if(channelOffLine1 != null){
                    //<1>.添加线下自营渠道->offlineCanalListDTOList
                    addSelCustomStrategyToOffLineDTO(offlineCanalListDTOList,channelOffLine1);
                }

                if(channelOffLine2 != null){
                    //<2>.封装线下代理商渠道->offlineCanalListDTOList
                    addAgentStrategyToOffLineDTO(offlineCanalListDTOList,channelOffLine2);
                }
            }

            //<3>.添加官方平台渠道->onlineSelfListDTOList
            addOnlineOfficePlatformToOnlineDTO(onlineSelfListDTOList,scenicProductSaleStrategy);

            //<4>.添加第三方平台渠道->onlineSelfListDTOList
            addOnlineOtherPlatformToOnlineDTO(onlineSelfListDTOList,scenicProductSaleStrategy);

            //<5>.封装加幅有效期
            addValidDateToDTO(localFunProductReq,validDateDTOList,scenicProductSaleStrategy,offlineCanalListDTOList,onlineSelfListDTOList);

        }
        return validDateDTOList;
    }


    @Override
    public Result<List<LocalFunProductSaleStrategyDTO>> localFunProductEditDetai(LocalFunProductEditReq scenicProductEditReq) {
        List<LocalFunProductSaleStrategyDTO> saleStrategyDTOS = new ArrayList<>();
        QueryWrapper<LocalFunProductCostStrategy> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", scenicProductEditReq.getId());
        List<LocalFunProductCostStrategy> scenicProductCostStrategies = localFunProductCostStrategyMapper.selectList(queryWrapper);
        if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(scenicProductCostStrategies)) {
            for (LocalFunProductCostStrategy scenicProductCostStrategy : scenicProductCostStrategies) {
                LocalFunProductSaleStrategyDTO scenicProductSaleStrategyDTO = new LocalFunProductSaleStrategyDTO();
                scenicProductSaleStrategyDTO.setName(scenicProductCostStrategy.getName());
                QueryWrapper<LocalFunProductSaleStrategyVaildDate> vaildDateQueryWrapper = new QueryWrapper<>();
                vaildDateQueryWrapper.eq("strategy_id", scenicProductCostStrategy.getId());
                List<LocalFunProductSaleStrategyVaildDate> list =localFunProductSaleStrategyVaildDateMapper.selectList(vaildDateQueryWrapper);
                List<LocalFunTimeDTO> timeDTOList = new ArrayList<>();
                if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(list)) {
                    for (LocalFunProductSaleStrategyVaildDate vaildDate : list) {
                        LocalFunTimeDTO scenicTimeDTO = new LocalFunTimeDTO();
                        scenicTimeDTO.setBeginTime(vaildDate.getTimeBegin());
                        scenicTimeDTO.setEndTime(vaildDate.getTimeEnd());
                        timeDTOList.add(scenicTimeDTO);
                    }
                }
                scenicProductSaleStrategyDTO.setTime(timeDTOList);
                //查询线下渠道
                ChannelSaleDTO channelSaleDTO = new ChannelSaleDTO();
                LocalFunProductOfflineChannelDTO scenicProductOfflineChannelDTO = new LocalFunProductOfflineChannelDTO();
                //自营渠道
                QueryWrapper<LocalFunProductChannelOffline> offlineQueryWrapper = new QueryWrapper<>();
                offlineQueryWrapper.eq("product_id", scenicProductCostStrategy.getProductId());
                offlineQueryWrapper.eq("strategy_id", scenicProductCostStrategy.getId());
                LocalFunProductChannelOffline scenicProductChannelOffline = localFunProductChannelOfflineMapper.selectOne(offlineQueryWrapper);
                if (scenicProductChannelOffline != null && scenicProductChannelOffline.getChannelType() == 1) {
                    if (scenicProductChannelOffline.getVisableType() == 2) {
                        QueryWrapper<LocalFunProductChannelOfflineSelfCustom> selfCustomQueryWrapper = new QueryWrapper<>();
                        selfCustomQueryWrapper.eq("product_id",scenicProductCostStrategy.getProductId());
                        selfCustomQueryWrapper.eq("offline_id",scenicProductChannelOffline.getId());
                        LocalFunProductChannelOfflineSelfCustom selfCustom = localFunProductChannelOfflineSelfCustomMapper.selectOne(selfCustomQueryWrapper);
                        if(selfCustom != null){
                            scenicProductOfflineChannelDTO = EntityUtil.copy(selfCustom, LocalFunProductOfflineChannelDTO.class);
                            scenicProductOfflineChannelDTO.setVisableType(scenicProductChannelOffline.getVisableType());
                        }
                    } else if(scenicProductChannelOffline.getVisableType() == 3){
                        List<LocalFunProductChannelOfflineSelfCustomDTO> scenicProductChannelOfflineSelfCustomDTOList = new ArrayList<>();
                        QueryWrapper<LocalFunProductChannelOfflineSelfCustom> selfCustomQueryWrapper = new QueryWrapper<>();
                        selfCustomQueryWrapper.eq("product_id",scenicProductCostStrategy.getProductId());
                        selfCustomQueryWrapper.eq("offline_id",scenicProductChannelOffline.getId());
                        selfCustomQueryWrapper.eq("is_delete",0);
                        List<LocalFunProductChannelOfflineSelfCustom> selfCustoms = localFunProductChannelOfflineSelfCustomMapper.selectList(selfCustomQueryWrapper);
                        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(selfCustoms)){
                            for(LocalFunProductChannelOfflineSelfCustom selfCustom : selfCustoms){
                                LocalFunProductChannelOfflineSelfCustomDTO scenicProductChannelOfflineSelfCustomDTO = EntityUtil.copy(selfCustom, LocalFunProductChannelOfflineSelfCustomDTO.class);
                                scenicProductChannelOfflineSelfCustomDTOList.add(scenicProductChannelOfflineSelfCustomDTO);
                                scenicProductOfflineChannelDTO.setScenicProductChannelOfflineSelfCustomDTOList(scenicProductChannelOfflineSelfCustomDTOList);
                            }
                        }
                    }
                    channelSaleDTO.setScenicProductOfflineChannelDTO(scenicProductOfflineChannelDTO);
                }else if(scenicProductChannelOffline != null && scenicProductChannelOffline.getChannelType() == 2){
                    //代理商
                    LocalFunProductAgentDTO scenicProductAgentDTO = new LocalFunProductAgentDTO();
                    if (scenicProductChannelOffline.getVisableType() == 2) {
                        QueryWrapper<LocalFunProductChannelOfflineAgentCustom> customQueryWrapper = new QueryWrapper<>();
                        customQueryWrapper.eq("product_id",scenicProductCostStrategy.getProductId());
                        customQueryWrapper.eq("offline_id",scenicProductChannelOffline.getId());
                        customQueryWrapper.eq("is_delete",0);
                        LocalFunProductChannelOfflineAgentCustom agentCustom = localFunProductChannelOfflineAgentCustomMapper.selectOne(customQueryWrapper);
                        if(null != agentCustom){
                            scenicProductAgentDTO = EntityUtil.copy(agentCustom, LocalFunProductAgentDTO.class);
                            scenicProductAgentDTO.setVisableType(scenicProductChannelOffline.getChannelType());
                        }
                    }else if(scenicProductChannelOffline.getVisableType() == 3){
                        List<LocalFunProductChannelOfflineAgentCustomDTO> scenicProductChannelOfflineAgentCustomDTOList = new ArrayList<>();
                        QueryWrapper<LocalFunProductChannelOfflineAgentCustom> customQueryWrapper = new QueryWrapper<>();
                        customQueryWrapper.eq("product_id",scenicProductCostStrategy.getProductId());
                        customQueryWrapper.eq("offline_id",scenicProductChannelOffline.getId());
                        customQueryWrapper.eq("is_delete",0);
                        List<LocalFunProductChannelOfflineAgentCustom> agentCustomList = localFunProductChannelOfflineAgentCustomMapper.selectList(customQueryWrapper);
                        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(agentCustomList)){
                            for(LocalFunProductChannelOfflineAgentCustom agentCustom : agentCustomList){
                                LocalFunProductChannelOfflineAgentCustomDTO agentCustomDTO = EntityUtil.copy(agentCustom, LocalFunProductChannelOfflineAgentCustomDTO.class);
                                scenicProductChannelOfflineAgentCustomDTOList.add(agentCustomDTO);
                            }
                            scenicProductAgentDTO.setScenicProductChannelOfflineAgentCustomDTOList(scenicProductChannelOfflineAgentCustomDTOList);
                        }
                    }
                    channelSaleDTO.setScenicProductAgentDTO(scenicProductAgentDTO);
                }
                //线上官方平台
                List<LocalFunProductChannelOnlineSelfPlatformDTO> scenicProductChannelOnlineSelfPlatformDTOList = new ArrayList<>();
                QueryWrapper<LocalFunProductChannelOnlineSelfPlatform> platformQueryWrapper = new QueryWrapper<>();
                platformQueryWrapper.eq("is_delete",0);
                platformQueryWrapper.eq("product_id",scenicProductCostStrategy.getProductId());
                List<LocalFunProductChannelOnlineSelfPlatform> selfPlatformList = new ArrayList<>();
                if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(selfPlatformList)){
                    for(LocalFunProductChannelOnlineSelfPlatform selfPlatform : selfPlatformList){
                        LocalFunProductChannelOnlineSelfPlatformDTO selfPlatformDTO = EntityUtil.copy(selfPlatform, LocalFunProductChannelOnlineSelfPlatformDTO.class);
                        scenicProductChannelOnlineSelfPlatformDTOList.add(selfPlatformDTO);
                    }
                    channelSaleDTO.setScenicProductChannelOnlineSelfPlatformDTOList(scenicProductChannelOnlineSelfPlatformDTOList);
                }
                //第三方平台
                List<LocalFunProductChannelOnlineThirdPlatformDTO> scenicProductChannelOnlineThirdPlatformDTOList = new ArrayList<>();
                QueryWrapper<LocalFunProductChannelOnlineThirdPlatform> scenicProductChannelOnlineThirdPlatformQueryWrapper = new QueryWrapper();
                scenicProductChannelOnlineThirdPlatformQueryWrapper.eq("product_id",scenicProductCostStrategy.getProductId());
                List<LocalFunProductChannelOnlineThirdPlatform> platforms = channelOnlineThirdPlatformMapper.selectList(scenicProductChannelOnlineThirdPlatformQueryWrapper);
                if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(platforms)){
                    for(LocalFunProductChannelOnlineThirdPlatform selfPlatform : platforms){
                        LocalFunProductChannelOnlineThirdPlatformDTO scenicProductChannelOnlineThirdPlatformDTO = EntityUtil.copy(selfPlatform, LocalFunProductChannelOnlineThirdPlatformDTO.class);
                        scenicProductChannelOnlineThirdPlatformDTOList.add(scenicProductChannelOnlineThirdPlatformDTO);
                    }
                    channelSaleDTO.setScenicProductChannelOnlineThirdPlatformDTOList(scenicProductChannelOnlineThirdPlatformDTOList);
                }
                scenicProductSaleStrategyDTO.setChannelSaleDTO(channelSaleDTO);
                saleStrategyDTOS.add(scenicProductSaleStrategyDTO);
            }
        }
        return Result.success(saleStrategyDTOS);
    }

    @Override
    @Transactional
    public Result localFunProductEdit(LocalFunProductBatchSaleStrategyReq req, TokenUser currentUser) {
        Long userId = currentUser == null ? null : currentUser.getId();
        QueryWrapper<LocalFunProductSaleStrategy> strategyQueryWrapper = new QueryWrapper<>();
        strategyQueryWrapper.eq("is_delete",0);
        strategyQueryWrapper.eq("product_id",req.getLocalFunProductIdList().get(0));
        List<LocalFunProductSaleStrategy> strategyList = localFunProductSaleStrategyMapper.selectList(strategyQueryWrapper);
        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(strategyList)){
            //清空策略
            localFunProductSaleStrategyMapper.clearByProductId(req.getLocalFunProductIdList().get(0),currentUser.getId());
            //清空有效期
            localFunProductSaleStrategyVaildDateMapper.clearByProductId(req.getLocalFunProductIdList().get(0),currentUser.getId());
            //清空门票产品线下渠道权限范围表
            localFunProductChannelOfflineMapper.clearByProductId(req.getLocalFunProductIdList().get(0),currentUser.getId());
            //清空门票线下自营自定义权限
            localFunProductChannelOfflineSelfCustomMapper.clearByProductId(req.getLocalFunProductIdList().get(0),currentUser.getId());
            //清空门票线下代理商自定义权限
            localFunProductChannelOfflineAgentCustomMapper.clearByProductId(req.getLocalFunProductIdList().get(0),currentUser.getId());
            //清空门票线上渠道第三方平台
            channelOnlineThirdPlatformMapper.clearByProductId(req.getLocalFunProductIdList().get(0),currentUser.getId());
            //清空门票线上自营自定义权限
            channelOnlineSelfPlatformMapper.clearByProductId(req.getLocalFunProductIdList().get(0),currentUser.getId());
        }
        if (req.getLocalFunProductIdList() != null && req.getLocalFunProductIdList().size() >= 1) {
            Long productId = req.getLocalFunProductIdList().get(0);
            List<LocalFunProductSaleStrategyReq> strategyReqlist = req.getStrategyList();
            if (strategyList != null && strategyList.size() >= 1) {
                for (LocalFunProductSaleStrategyReq scenicProductSaleStrategyReq : strategyReqlist) {
                    //新增门票销售加幅策略
                    Long id = SnowflakeIdWorker.nextId();
                    LocalFunProductSaleStrategy scenicProductSaleStrategy = new LocalFunProductSaleStrategy();
                    scenicProductSaleStrategy.setId(id);
                    scenicProductSaleStrategy.setCreateId(userId);
                    scenicProductSaleStrategy.setIsDeleted(0);
                    scenicProductSaleStrategy.setGmtCreate(LocalDateTime.now());
                    scenicProductSaleStrategy.setProductId(productId);
                    scenicProductSaleStrategy.setName(scenicProductSaleStrategyReq.getName());
                    localFunProductSaleStrategyMapper.insert(scenicProductSaleStrategy);
                    //新增门票销售价格加幅有效期
                    List<LocalFunTimeDTO> time = scenicProductSaleStrategyReq.getTime();
                    if (time != null && time.size() >= 1) {
                        List<LocalFunProductSaleStrategyVaildDate> list = new ArrayList<>();
                        for (LocalFunTimeDTO scenicTimeDTO : time) {
                            LocalFunProductSaleStrategyVaildDate scenicProductSaleStrategyVaildDate = new LocalFunProductSaleStrategyVaildDate();
                            scenicProductSaleStrategyVaildDate.setProductId(productId);
                            scenicProductSaleStrategyVaildDate.setGmtCreate(LocalDateTime.now());
                            scenicProductSaleStrategyVaildDate.setTimeBegin(scenicTimeDTO.getBeginTime());
                            scenicProductSaleStrategyVaildDate.setTimeEnd(scenicTimeDTO.getEndTime());
                            scenicProductSaleStrategyVaildDate.setStrategyId(id);
                            list.add(scenicProductSaleStrategyVaildDate);
                        }
                        localFunProductSaleStrategyVaildDateMapper.insertBatchSomeColumn(list);
                    }
                    ChannelSaleReq channelSaleReq = scenicProductSaleStrategyReq.getChannelSaleReq();
                    //新增线下渠道
                    LocalFunProductOfflineChannelReq scenicProductOfflineChannelReq = channelSaleReq.getLocalFunProductOfflineChannelReq();
                    if (scenicProductOfflineChannelReq != null) {
                        Long officeId = SnowflakeIdWorker.nextId();
                        LocalFunProductChannelOfflineSelfCustom scenicProductChannelOfflineSelfCustom = new LocalFunProductChannelOfflineSelfCustom();
                        scenicProductChannelOfflineSelfCustom.setId(SnowflakeIdWorker.nextId());
                        scenicProductChannelOfflineSelfCustom.setProductId(productId);
                        scenicProductChannelOfflineSelfCustom.setGmtCreate(LocalDateTime.now());
                        scenicProductChannelOfflineSelfCustom.setCreateId(userId);
                        scenicProductChannelOfflineSelfCustom.setOfflineId(officeId);
                        scenicProductChannelOfflineSelfCustom.setIsDeleted(0);
                        LocalFunProductChannelOffline scenicProductChannelOffline = new LocalFunProductChannelOffline();
                        scenicProductChannelOffline.setProductId(productId);
                        scenicProductChannelOffline.setChannelType(1);
                        scenicProductChannelOffline.setCreateId(userId);
                        scenicProductChannelOffline.setGmtCreate(LocalDateTime.now());
                        scenicProductChannelOffline.setIsDeleted(0);
                        scenicProductChannelOffline.setStrategyId(id);
                        scenicProductChannelOffline.setId(officeId);
                        switch (scenicProductOfflineChannelReq.getVisableType()) {
                            case 1:
                                scenicProductChannelOffline.setVisableType(1);
                                localFunProductChannelOfflineMapper.insert(scenicProductChannelOffline);
                                break;
                            case 2:
                                scenicProductChannelOffline.setVisableType(2);
                                localFunProductChannelOfflineMapper.insert(scenicProductChannelOffline);
                                if (scenicProductOfflineChannelReq.getAdjustType() == 1) {
                                    scenicProductChannelOfflineSelfCustom.setAdjustType(1);
                                    scenicProductChannelOfflineSelfCustom.setAmount(scenicProductOfflineChannelReq.getAmount());
                                } else if (scenicProductOfflineChannelReq.getAdjustType() == 2) {
                                    scenicProductChannelOfflineSelfCustom.setAdjustType(2);
                                    scenicProductChannelOfflineSelfCustom.setPercent(scenicProductOfflineChannelReq.getPercent());
                                } else {
                                    break;
                                }
                                if (scenicProductOfflineChannelReq.getIsLimit() == 0) {
                                    scenicProductChannelOfflineSelfCustom.setIsLimit(0);
                                } else if (scenicProductOfflineChannelReq.getIsLimit() == 1) {
                                    scenicProductChannelOfflineSelfCustom.setIsLimit(1);
                                    scenicProductChannelOfflineSelfCustom.setLimitNum(scenicProductOfflineChannelReq.getLimitNum());
                                }
                                localFunProductChannelOfflineSelfCustomMapper.insert(scenicProductChannelOfflineSelfCustom);
                                break;
                            case 3:
                                scenicProductChannelOffline.setVisableType(3);
                                localFunProductChannelOfflineMapper.insert(scenicProductChannelOffline);
                                List<LocalFunProductChannelOfflineSelfCustomReq> scenicProductChannelOfflineSelfCustomReqList = scenicProductOfflineChannelReq.getChannelOfflineSelfCustomReqs();
                                if (scenicProductChannelOfflineSelfCustomReqList != null) {
                                    for (LocalFunProductChannelOfflineSelfCustomReq customReq : scenicProductChannelOfflineSelfCustomReqList) {
                                        scenicProductChannelOfflineSelfCustom.setCheckType(customReq.getCheckType());
                                        scenicProductChannelOfflineSelfCustom.setName(customReq.getName());
                                        scenicProductChannelOfflineSelfCustom.setRelationId(customReq.getRelationId());
                                        if (scenicProductOfflineChannelReq.getAdjustType() == 1) {
                                            scenicProductChannelOfflineSelfCustom.setAdjustType(1);
                                            scenicProductChannelOfflineSelfCustom.setAmount(scenicProductOfflineChannelReq.getAmount());
                                        } else if (scenicProductOfflineChannelReq.getAdjustType() == 2) {
                                            scenicProductChannelOfflineSelfCustom.setAdjustType(2);
                                            scenicProductChannelOfflineSelfCustom.setPercent(scenicProductOfflineChannelReq.getPercent());
                                        } else {
                                            break;
                                        }
                                        if (scenicProductOfflineChannelReq.getIsLimit() == 0) {
                                            scenicProductChannelOfflineSelfCustom.setIsLimit(0);
                                        } else if (scenicProductOfflineChannelReq.getIsLimit() == 1) {
                                            scenicProductChannelOfflineSelfCustom.setIsLimit(1);
                                            scenicProductChannelOfflineSelfCustom.setLimitNum(scenicProductOfflineChannelReq.getLimitNum());
                                        }
                                        localFunProductChannelOfflineSelfCustomMapper.insert(scenicProductChannelOfflineSelfCustom);
                                    }
                                }
                                break;
                            default:
                                break;
                        }

                    }
                    //新增代理商
                    LocalFunProductAgentReq scenicProductAgentReq = channelSaleReq.getLocalFunProductAgentReq();
                    if (scenicProductAgentReq != null) {
                        Long offLineId = SnowflakeIdWorker.nextId();
                        LocalFunProductChannelOffline scenicProductChannelOffline = new LocalFunProductChannelOffline();
                        scenicProductChannelOffline.setProductId(productId);
                        scenicProductChannelOffline.setChannelType(2);
                        scenicProductChannelOffline.setCreateId(userId);
                        scenicProductChannelOffline.setIsDeleted(0);
                        scenicProductChannelOffline.setStrategyId(id);
                        scenicProductChannelOffline.setId(offLineId);
                        //代理商
                        LocalFunProductChannelOfflineAgentCustom scenicProductChannelOfflineAgentCustom = new LocalFunProductChannelOfflineAgentCustom();
                        scenicProductChannelOfflineAgentCustom.setProductId(productId);
                        scenicProductChannelOfflineAgentCustom.setGmtCreate(LocalDateTime.now());
                        scenicProductChannelOfflineAgentCustom.setCreateId(userId);
                        scenicProductChannelOfflineAgentCustom.setOfflineId(offLineId);
                        scenicProductChannelOfflineAgentCustom.setId(SnowflakeIdWorker.nextId());
                        switch (scenicProductAgentReq.getVisableType()) {
                            case 1:
                                scenicProductChannelOffline.setVisableType(1);
                                localFunProductChannelOfflineMapper.insert(scenicProductChannelOffline);
                                break;
                            case 2:
                                scenicProductChannelOffline.setVisableType(2);
                                localFunProductChannelOfflineMapper.insert(scenicProductChannelOffline);
                                if (scenicProductAgentReq.getAdjustType() == 1) {
                                    scenicProductChannelOfflineAgentCustom.setAmount(scenicProductAgentReq.getAmount());
                                    scenicProductChannelOfflineAgentCustom.setAdjustType(1);
                                } else if (scenicProductAgentReq.getAdjustType() == 2) {
                                    scenicProductChannelOfflineAgentCustom.setAdjustType(2);
                                    scenicProductChannelOfflineAgentCustom.setPercent(scenicProductAgentReq.getPercent());
                                } else {
                                    break;
                                }
                                if (scenicProductAgentReq.getIsLimit() == 0) {
                                    scenicProductChannelOfflineAgentCustom.setLimitNum(scenicProductAgentReq.getLimitNum());
                                } else if (scenicProductAgentReq.getIsLimit() == 1) {
                                    scenicProductChannelOfflineAgentCustom.setIsLimit(1);
                                    scenicProductChannelOfflineAgentCustom.setLimitNum(scenicProductAgentReq.getLimitNum());
                                }
                                localFunProductChannelOfflineAgentCustomMapper.insert(scenicProductChannelOfflineAgentCustom);
                                break;
                            case 3:
                                scenicProductChannelOffline.setVisableType(3);
                                localFunProductChannelOfflineMapper.insert(scenicProductChannelOffline);
                                List<LocalFunProductChannelOfflineAgentCustomReq> scenicProductChannelOfflineAgentCustomReqList = scenicProductAgentReq.getScenicProductChannelOfflineAgentCustomReqList();
                                if (scenicProductChannelOfflineAgentCustomReqList != null) {
                                    for (LocalFunProductChannelOfflineAgentCustomReq req1 : scenicProductChannelOfflineAgentCustomReqList) {
                                        scenicProductChannelOfflineAgentCustom.setAgentId(req1.getAgentId());
                                        scenicProductChannelOfflineAgentCustom.setAgentName(req1.getAgentName());
                                        if (req1.getAdjustType() == 1) {
                                            scenicProductChannelOfflineAgentCustom.setAdjustType(1);
                                            scenicProductChannelOfflineAgentCustom.setAmount(req1.getAmount());
                                        } else if (req1.getAdjustType() == 2) {
                                            scenicProductChannelOfflineAgentCustom.setAdjustType(2);
                                            scenicProductChannelOfflineAgentCustom.setPercent(req1.getPercent());
                                        } else {
                                            break;
                                        }
                                        if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                                            scenicProductChannelOfflineAgentCustom.setIsLimit(0);
                                        } else  {
                                            scenicProductChannelOfflineAgentCustom.setIsLimit(1);
                                            scenicProductChannelOfflineAgentCustom.setLimitNum(req1.getLimitNum());
                                        }
                                        localFunProductChannelOfflineAgentCustomMapper.insert(scenicProductChannelOfflineAgentCustom);
                                    }
                                }
                                break;
                            default:
                                break;
                        }
                    }
                    //新增线下渠道官方平台
                    List<LocalFunProductChannelOnlineSelfPlatformReq> scenicProductChannelOnlineSelfPlatformReqList = channelSaleReq.getLocalFunProductChannelOnlineSelfPlatformReqList();
                    if (scenicProductChannelOnlineSelfPlatformReqList != null) {
                        for (LocalFunProductChannelOnlineSelfPlatformReq req1 : scenicProductChannelOnlineSelfPlatformReqList) {
                            LocalFunProductChannelOnlineSelfPlatform scenicProductChannelOnlineSelfPlatform = new LocalFunProductChannelOnlineSelfPlatform();
                            scenicProductChannelOnlineSelfPlatform.setId(SnowflakeIdWorker.nextId());
                            scenicProductChannelOnlineSelfPlatform.setProductId(productId);
                            scenicProductChannelOnlineSelfPlatform.setCreateId(userId);
                            scenicProductChannelOnlineSelfPlatform.setIsDeleted(0);
                            scenicProductChannelOnlineSelfPlatform.setGmtCreate(LocalDateTime.now());
                            scenicProductChannelOnlineSelfPlatform.setChannelId(req1.getChannelId());
                            scenicProductChannelOnlineSelfPlatform.setChannelName(req1.getChannelName());
                            if (req1.getAdjustType() == 1) {
                                scenicProductChannelOnlineSelfPlatform.setAdjustType(1);
                                scenicProductChannelOnlineSelfPlatform.setAmount(req1.getAmount());
                            } else if (req1.getAdjustType() == 2) {
                                scenicProductChannelOnlineSelfPlatform.setAdjustType(2);
                                scenicProductChannelOnlineSelfPlatform.setPercent(req1.getPercent());
                            } else {
                                break;
                            }
                            if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                                scenicProductChannelOnlineSelfPlatform.setIsLimit(0);
                            }else {
                                scenicProductChannelOnlineSelfPlatform.setIsLimit(1);
                                scenicProductChannelOnlineSelfPlatform.setLimitNum(req1.getLimitNum());
                            }
                            channelOnlineSelfPlatformMapper.insert(scenicProductChannelOnlineSelfPlatform);
                        }
                    }
                    //新增线下渠道第三方平台
                    List<LocalFunProductChannelOnlineThirdPlatformReq> scenicProductChannelOnlineThirdPlatformReqList = channelSaleReq.getLocalFunProductChannelOnlineThirdPlatformReqList();
                    if (scenicProductChannelOnlineThirdPlatformReqList != null) {
                        for (LocalFunProductChannelOnlineThirdPlatformReq req1 : scenicProductChannelOnlineThirdPlatformReqList) {
                            LocalFunProductChannelOnlineThirdPlatform scenicProductChannelOnlineThirdPlatform = new LocalFunProductChannelOnlineThirdPlatform();
                            scenicProductChannelOnlineThirdPlatform.setProductId(productId);
                            scenicProductChannelOnlineThirdPlatform.setId(SnowflakeIdWorker.nextId());
                            scenicProductChannelOnlineThirdPlatform.setIsDeleted(0);
                            scenicProductChannelOnlineThirdPlatform.setCreateId(userId);
                            scenicProductChannelOnlineThirdPlatform.setPlatformId(req1.getPlatformId());
                            scenicProductChannelOnlineThirdPlatform.setPlatformName(req1.getPlatformName());
                            scenicProductChannelOnlineThirdPlatform.setGmtCreate(LocalDateTime.now());
                            if (req1.getAdjustType() == 1) {
                                scenicProductChannelOnlineThirdPlatform.setAdjustType(1);
                                scenicProductChannelOnlineThirdPlatform.setAmount(req1.getAmount());
                            } else if (req1.getAdjustType() == 2) {
                                scenicProductChannelOnlineThirdPlatform.setAdjustType(2);
                                scenicProductChannelOnlineThirdPlatform.setPercent(req1.getPercent());
                            } else {
                                break;
                            }
                            if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                                scenicProductChannelOnlineThirdPlatform.setIsLimit(0);
                            } else {
                                scenicProductChannelOnlineThirdPlatform.setIsLimit(1);
                                scenicProductChannelOnlineThirdPlatform.setLimitNum(req1.getLimitNum());
                            }
                            channelOnlineThirdPlatformMapper.insert(scenicProductChannelOnlineThirdPlatform);
                        }
                    }

                }
            }
        }
        return Result.success();
    }

    @Override
    public Result<List<LocalFunProductListDTO>> localFunProductList(LocalFunProductReq scenicProductReq) {
        QueryWrapper<LocalFunProduct> scenicProductQueryWrapper = new QueryWrapper<>();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(scenicProductReq.getCityId())){
            scenicProductQueryWrapper.eq("city_id",scenicProductReq.getCityId());
            scenicProductQueryWrapper.eq("is_delete",0);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(scenicProductReq.getScenicId())){
            scenicProductQueryWrapper.eq("fun_type",scenicProductReq.getScenicId());
            scenicProductQueryWrapper.eq("is_delete",0);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(scenicProductReq.getProductName())){
            scenicProductQueryWrapper.lambda().like(LocalFunProduct::getName,scenicProductReq.getProductName());
            scenicProductQueryWrapper.eq("is_delete",0);
        }
        List<LocalFunProduct> list = localFunProductMapper.selectList(scenicProductQueryWrapper);
        List<LocalFunProductListDTO> scenicProductListDTOS = new ArrayList<>();
        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(list)){
            for(LocalFunProduct scenicProduct : list){
                LocalFunProductListDTO scenicProductListDTO = EntityUtil.copy(scenicProduct, LocalFunProductListDTO.class);
                scenicProductListDTOS.add(scenicProductListDTO);
            }
        }
        return Result.success(scenicProductListDTOS);
    }

    @Override
    public Result<LocalFunProductTicketDTO> localFunProductTicketPrice(LocalFunProductTicketReq scenicProductTicketReq) {
        LocalFunProductTicketDTO scenicProductTicketDTO = new LocalFunProductTicketDTO();
        QueryWrapper<LocalFunProduct> scenicProductQueryWrapper = new QueryWrapper<>();
        scenicProductQueryWrapper.eq("is_deleted",0);
        scenicProductQueryWrapper.eq("id",scenicProductTicketReq.getProductId());
        LocalFunProduct scenicProduct = localFunProductMapper.selectOne(scenicProductQueryWrapper);
        if(scenicProduct != null){
            QueryWrapper<LocalFunProductCostStrategySpecStock> stockQueryWrapper = new QueryWrapper<>();
            stockQueryWrapper.eq("is_deleted",0);
            stockQueryWrapper.eq("product_id",scenicProduct.getId());
            List<LocalFunProductCostStrategySpecStock> list = localFunProductCostStrategySpecStockMapper.selectList(stockQueryWrapper);
            if("1".equals(scenicProduct.getReserveChargeType())){
                scenicProductTicketDTO.setCharge(scenicProduct.getReserveCharge());
            }
            if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(list)){
                LocalFunProductCostStrategySpecStock scenicProductCostStrategySpecStock = list.get(0);
                if(scenicProductCostStrategySpecStock != null && "2".equals(scenicProduct.getReserveChargeType())){
                    scenicProductTicketDTO.setCharge(scenicProductCostStrategySpecStock.getCostPrice().multiply(scenicProduct.getReserveCharge()).divide(new BigDecimal("100")));
                }
            }
        }
        return Result.success(scenicProductTicketDTO);
    }

    @Override
    public Result<LocalFunProductDetailByIdDTO> localFunProductDetailByIdDTO(LocalFunProductDetailReq scenicProductDetailReq) {
        LocalFunProduct scenicProduct = localFunProductMapper.selectById(scenicProductDetailReq.getId());
        LocalFunProductDetailByIdDTO scenicProductDetailByIdDTO = null;
        if(scenicProduct != null){
            scenicProductDetailByIdDTO = EntityUtil.copy(scenicProduct, LocalFunProductDetailByIdDTO.class);
        }else {
            throw new BusinessException(SystemError.CUSTOM_ORDER_4008);
        }
        return Result.success(scenicProductDetailByIdDTO);
    }

    @Override
    public Result<LocalFunProductTicketDetailDTO> localFunProductTicketDetail(LocalFunProductTicketDetailReq scenicProductTicketDetailReq) {
        LocalFunProductTicket scenicProductTicket = localFunProductTicketMapper.selectById(scenicProductTicketDetailReq.getId());
        LocalFunProductTicketDetailDTO scenicProductTicketDetailDTO = new LocalFunProductTicketDetailDTO();
        if(scenicProductTicket != null){
            scenicProductTicketDetailDTO.setStockNumber(scenicProductTicket.getStockNumber());
            scenicProductTicketDetailDTO.setSupplierTicketNumber(scenicProductTicket.getSupplierTicketNumber());
            scenicProductTicketDetailDTO.setProductId(scenicProductTicket.getProductId().toString());
        }
        return Result.success(scenicProductTicketDetailDTO);
    }


    @Override
    public Result modifyProductTicket(List<LocalFunProductTicketListReq> scenicProductTicketListReqList,TokenUser tokenUser) {
        if(org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(scenicProductTicketListReqList)){
            for(LocalFunProductTicketListReq scenicProductTicketListReq : scenicProductTicketListReqList){
                LocalFunProductTicket scenicProductTicket = localFunProductTicketMapper.selectById(scenicProductTicketListReq.getTicketsProductId());
                scenicProductTicket.setSupplierTicketNumber(scenicProductTicketListReq.getSupplierTicketNumber());
                scenicProductTicket.setGmtModified(LocalDateTime.now());
                scenicProductTicket.setModifiedId(tokenUser.getId());
                localFunProductTicketMapper.updateById(scenicProductTicket);
            }
        }
        return Result.success();
    }

    @Override
    public Result<LocalFunProductReceiptDTO> localFunProductDetail(LocalFunProductDetailReq scenicProductDetailReq) {
        LocalFunProduct scenicProduct = localFunProductMapper.selectById(scenicProductDetailReq.getId());
        LocalFunProductReceiptDTO scenicProductReceiptDTO = EntityUtil.copy(scenicProduct, LocalFunProductReceiptDTO.class);
        //成本价
        //规格属性
        List<LocalFunProductSpecAttrDTO> scenicProductSpecAttrDTOList = new ArrayList<>();
        QueryWrapper<LocalFunProductCostStrategySpecAttr> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",Lists.newArrayList(scenicProductDetailReq.getAttrId1(),scenicProductDetailReq.getAttrId2()));
        List<LocalFunProductCostStrategySpecAttr> list = costStrategySpecAttrMapper.selectList(queryWrapper);

        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(entity->{
                LocalFunProductSpecAttrDTO scenicProductSpecAttrDTO = new LocalFunProductSpecAttrDTO();
                scenicProductSpecAttrDTO.setSpecName(entity.getSpecName());
                scenicProductSpecAttrDTO.setAttributeName(entity.getAttributeName());
                scenicProductSpecAttrDTOList.add(scenicProductSpecAttrDTO);
            });
        }
        scenicProductReceiptDTO.setScenicProductSpecAttrDTOList(scenicProductSpecAttrDTOList);
        return Result.success(scenicProductReceiptDTO);
    }

    @Override
    public Result<PageResponse<LocalFunDyTicketProductDTO>> getLocalFunDyTicketProductList(LocalFunDyTicketProductReq req) {
        IPage<LocalFunProduct> iPage = new Page<>(req.getPageNo(), req.getPageSize());
        //查询条件
        QueryWrapper<LocalFunProduct> queryWrapper = queryParam(req);
        //分页查询结果集
        IPage<LocalFunProduct> insuranceIPage = baseMapper.selectPage(iPage, queryWrapper);

        if (CollectionUtils.isNotEmpty(insuranceIPage.getRecords())) {
            List<LocalFunDyTicketProductDTO> localFunResourceDTOList = EntityUtil.copyList(insuranceIPage.getRecords(),
                    LocalFunDyTicketProductDTO.class);

            //設置成本有效期和幅加策略有效期
            setValidateTime(localFunResourceDTOList);

            //权限校验产品过滤
            localFunResourceDTOList = productPrivilegeVisitable(localFunResourceDTOList,req.getUserId());
            return Result.success(new PageResponse(localFunResourceDTOList, iPage.getCurrent() == 1, localFunResourceDTOList.size() <= (iPage.getCurrent() * localFunResourceDTOList.size()), localFunResourceDTOList.size(), iPage.getCurrent(), iPage.getSize()));
        }
        return Result.success(new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize()));
    }

    /**
     * 當前日期對應的策略
     * @param queryDate
     * @param productId
     * @return
     */
    @Override
    public Result<Long> getExactStrategyId(LocalDate queryDate, Long productId) {
        Long strategyId = localFunProductSaleStrategyMapper.getStrategyId(queryDate, productId);
        return Result.success(strategyId);
    }

    @Override
    public Result<PageResponse<AgentDto>> queryAgentList(AgentReq req) {
        IPage<LocalFunProduct> iPage = new Page<>(req.getPageNo(), req.getPageSize());
        IPage<AgentDto> agentList = localFunProductMapper.queryAgentList(req,LocalDate.now(),iPage);

        //校验
        if(CollectionUtils.isEmpty(agentList) || CollectionUtils.isEmpty(agentList.getRecords())) {
            return Result.success(new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize()));
        }
        boolean isForbid = agentList.getRecords().stream().anyMatch(dto -> dto.getVisableType() == 1);
        if(isForbid){
            return Result.success(new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize()));
        }

        //获取渠道权限
        AgentDto agentDto = agentList.getRecords().stream().findFirst().orElse(null);
        if(agentDto != null){
            //返回所有代理商
            if(agentDto.getVisableType() == 2){

                SysAgentQueryListReq usableListReq = new SysAgentQueryListReq();
                if(StringUtils.isNotEmpty(req.getAgentName())){
                    usableListReq.setGroupName(req.getAgentName());
                }
                usableListReq.setPageNo(req.getPageNo());
                usableListReq.setPageSize(req.getPageSize());
                usableListReq.setStatus(1);
                usableListReq.setCheckStatus(3);

                PageResponse<SysAgentQueryListDTO> listResult = sysAgentService.queryAgentList(usableListReq, null);
                if(listResult != null){
                    List<AgentDto> agentDtos = listResult.getRecords().stream().map(entity -> {
                        AgentDto dto = new AgentDto();
                        dto.setId(entity.getId());
                        dto.setAgentName(entity.getGroupCnName());
                        dto.setAgentFee(agentDto.getAgentFee());
                        //加辐后的价格：成本价+代理加辐费
                        dto.setPrice(Objects.isNull(agentDto.getPrice()) ? BigDecimal.ZERO : agentDto.getPrice()
                                .add(Objects.isNull(agentDto.getAgentFee()) ? BigDecimal.ZERO : agentDto.getAgentFee()));
                        return dto;
                    }).collect(Collectors.toList());
                    return Result.success(new PageResponse<AgentDto>(agentDtos, iPage.getCurrent() == 1,
                            iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize()));
                }else {
                    return Result.success(new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize()));
                }
            }
        }
        //按照所选代理商返回
        agentList.getRecords().forEach(agent->agent.setPrice(Objects.isNull(agent.getPrice())?BigDecimal.ZERO:agent.getPrice()
                .add(Objects.isNull(agent.getAgentFee())?BigDecimal.ZERO :agent.getAgentFee())));
        return Result.success(new PageResponse<>(agentList.getRecords(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize()));
    }

    @Override
    public BigDecimal queryLocalFunPrice(Long localFunId, Long channelId) {
        return null;
    }

    /**
     * 內部提供-套票
     * @param strategyType 加幅类型，1：自营；2：代理；3：官方平台；4：第三方平台；
     * @param productId 产品ID
     * @param departureDate 出发日期
     * @param relId 关联ID，strategyType(1：用户ID；2：代理ID；3：渠道ID；4：渠道ID)
     * @param attrId1   規格ID1
     * @param attrId2   規格ID2  倆個規格ID都空，則選擇默認最小價格展示
     * @return
     */
    @Override
    public LocalFunPriceRemainderDTO findLocalFunSalePriceInfoHandle(int strategyType, Long productId, LocalDate departureDate, Long relId, Long attrId1, Long attrId2) {
        LocalFunPriceRemainderDTO priceRemainder = new LocalFunPriceRemainderDTO();
        //1.构建成本價+加幅費
        switch (strategyType){
            case 1:
                List<LocalFunAddPriceDTO> allAttrsPriceList =baseMapper.queryOffLineSalePrice(productId,departureDate);
                //校验产品用户是否设置加辐费
                checkUserCandidate(relId, allAttrsPriceList);
                //构建产品价格信息
                buildOfflinePriceInfo(attrId1, attrId2, priceRemainder, allAttrsPriceList, departureDate,null);
                break;
            case 2:
                List<LocalFunAddPriceDTO> agentPriceList =baseMapper.querySaleAgentPrice(productId,departureDate);
                if(CollectionUtils.isEmpty(agentPriceList)){
                    throw new BusinessException(SystemError.LOCAL_FUN_18026);
                }
                //构建产品价格信息
                buildOfflinePriceInfo(attrId1, attrId2, priceRemainder, agentPriceList,departureDate,relId);
                break;
            case 3:
                //获取官方平台产品渠道的加辐
                List<LocalFunAddPriceDTO> officeDtoList = baseMapper.querySaleOfficePrice(productId,departureDate,relId);
                if(CollectionUtils.isEmpty(officeDtoList)){
                    throw new BusinessException(SystemError.LOCAL_FUN_18026);
                }
                //构建产品价格信息
                buildOfflinePriceInfo(attrId1, attrId2, priceRemainder, officeDtoList, departureDate, 1L);
                break;
            case 4:
                //获取第三方平台产品渠道的加辐
                List<LocalFunAddPriceDTO> thirdDtoList = baseMapper.querySaleThirdPrice(productId,departureDate,relId);
                if(CollectionUtils.isEmpty(thirdDtoList)){
                    throw new BusinessException(SystemError.LOCAL_FUN_18026);
                }
                //构建产品价格信息
                buildOfflinePriceInfo(attrId1, attrId2, priceRemainder, thirdDtoList, departureDate, 1L);
                break;
            default:
                break;
        }

        //2.设置預定服務費
        LocalFunProduct localFunProduct = localFunProductMapper.selectById(productId);
        if(localFunProduct == null){
            throw new BusinessException(SystemError.SHIP_PRODUCT_11006);
        }
        if(localFunProduct.getReserveChargeType() ==null || localFunProduct.getReserveCharge() == null){
            priceRemainder.setReserveCharge(BigDecimal.ZERO);
        }else {
            //1 金額
            if(localFunProduct.getReserveChargeType() == 1){
                priceRemainder.setReserveCharge(localFunProduct.getReserveCharge());
            }
            //百分比
            else {
                BigDecimal reserveCharge = priceRemainder.getCostPrice().multiply(localFunProduct.getReserveCharge().multiply(new BigDecimal(0.01)));
                priceRemainder.setReserveCharge(reserveCharge);
            }
        }
        return priceRemainder;
    }


    /**
     * 未设置加辐费，处理策略
     * @param departureDate
     * @param priceRemainder
     * @param localFunAddPriceDTOS
     */
    protected void obtainUnSetFee(LocalDate departureDate, LocalFunPriceRemainderDTO priceRemainder, List<LocalFunAddPriceDTO> localFunAddPriceDTOS) {
        //未设置加辐费
        List<LocalFunAddPriceDTO> nullSaleOfficePriceList = localFunAddPriceDTOS;
        LocalFunAddPriceDTO localFunAddPriceDTO = nullSaleOfficePriceList.stream().findFirst().orElse(null);
        if (localFunAddPriceDTO != null) {
            priceRemainder.setAttr1Name(localFunAddPriceDTO.getAttr1Name());
            priceRemainder.setAttr2Name(localFunAddPriceDTO.getAttr2Name());
            priceRemainder.setCostPrice(localFunAddPriceDTO.getCostPrice());
            priceRemainder.setExchangeRate(localFunAddPriceDTO.getExchangeRate());
            priceRemainder.setPrice(Objects.isNull(localFunAddPriceDTO.getCostPrice()) ? null : NumberUtil.getDecimalPercent(localFunAddPriceDTO.getCostPrice().multiply(localFunAddPriceDTO.getExchangeRate())));
            priceRemainder.setSolidNumber(querySolidNumber(localFunAddPriceDTO, departureDate));
        }
    }

    /**
     * 內部提供-套票
     * @param strategyType 加幅类型，1：自营；2：代理；3：官方平台；4：第三方平台；
     * @param productId 产品ID
     * @param departureDate 出发日期
     * @param relId 关联ID，strategyType(1：用户ID；2：代理ID；3：渠道ID；4：渠道ID)
     * @return
     */
    @Override
    public List<LocalFunPriceRemainderDTO> findLocalFunSalePriceInfoHandleList(int strategyType, Long productId, LocalDate departureDate, Long relId) {
        List<LocalFunPriceRemainderDTO> priceRemainderList = Lists.newArrayListWithExpectedSize(10);
        //1.设置預定服務費
        LocalFunProduct localFunProduct = localFunProductMapper.selectById(productId);
        if(localFunProduct == null){
            throw new BusinessException(SystemError.SHIP_PRODUCT_11006);
        }
        //2.构建成本價+加幅費
        switch (strategyType){
            case 1:
                List<LocalFunAddPriceDTO> allAttrsPriceList =baseMapper.queryOffLineSalePrice(productId,departureDate);
                //校验产品用户是否设置加辐费
                checkUserCandidate(relId, allAttrsPriceList);
                //构建产品价格信息
                priceRemainderList.addAll(buildOfflinePriceInfo2(localFunProduct,allAttrsPriceList, departureDate));
                break;
            case 2:
                List<LocalFunAddPriceDTO> agentPriceList =baseMapper.querySaleAgentPrice(productId,departureDate);
                if(CollectionUtils.isEmpty(agentPriceList)){
                    throw new BusinessException(SystemError.LOCAL_FUN_18026);
                }
                //构建产品价格信息
                priceRemainderList.addAll(buildOfflinePriceInfo2(localFunProduct, agentPriceList, departureDate));
                break;
            case 3:
                //获取官方平台产品渠道的加辐
                List<LocalFunAddPriceDTO> officeDtoList = baseMapper.querySaleOfficePrice(productId,departureDate,relId);
                if(CollectionUtils.isEmpty(officeDtoList)){
                    throw new BusinessException(SystemError.LOCAL_FUN_18027);
                }
                //构建产品价格信息
                priceRemainderList.addAll(buildOfflinePriceInfo2(localFunProduct, officeDtoList, departureDate));
                break;
            case 4:
                //获取第三方平台产品渠道的加辐
                List<LocalFunAddPriceDTO> thirdDtoList = baseMapper.querySaleThirdPrice(productId,departureDate,relId);
                if(CollectionUtils.isEmpty(thirdDtoList)){
                    throw new BusinessException(SystemError.LOCAL_FUN_18027);
                }
                //构建产品价格信息
                priceRemainderList.addAll(buildOfflinePriceInfo2(localFunProduct, thirdDtoList, departureDate));
                break;
            default:
                break;
        }
        return priceRemainderList;
    }

    private List<LocalFunPriceRemainderDTO> buildOfflinePriceInfo2(LocalFunProduct localFunProduct, List<LocalFunAddPriceDTO> thirdDtoList, LocalDate departureDate) {
        if(CollectionUtils.isNotEmpty(thirdDtoList)){
            return thirdDtoList.stream().map(entity->{
                LocalFunPriceRemainderDTO dto = new LocalFunPriceRemainderDTO();
                dto.setCostPrice(entity.getCostPrice());
                dto.setExchangeRate(entity.getExchangeRate());
                dto.setPrice(Objects.isNull(entity.getCostAndFee()) ? null :NumberUtil.getDecimalPercent(entity.getCostAndFee()));
                dto.setSolidNumber(querySolidNumber(entity,departureDate));

                BigDecimal reserveCharge;
                //1 金額
                if(localFunProduct.getReserveChargeType() == 1){
                    reserveCharge = localFunProduct.getReserveCharge();
                }
                //百分比
                else {
                    reserveCharge = entity.getCostPrice().multiply(localFunProduct.getReserveCharge().multiply(new BigDecimal(0.01)));
                }
                dto.setReserveCharge(reserveCharge);
                return dto;
            }).collect(Collectors.toList());
        }
        return Lists.newArrayListWithExpectedSize(1);
    }

    @Override
    public List<AgentDto> queryAgentList2(AgentReq req) {
        List<AgentDto> agentDtos1 = localFunProductMapper.queryAgentList2(req, LocalDate.now());

        //校验
        if(CollectionUtils.isEmpty(agentDtos1)) {
            return Lists.newArrayListWithExpectedSize(1);
        }
        boolean isForbid = agentDtos1.stream().anyMatch(dto -> dto.getVisableType() == 1);
        if(isForbid){
            return Lists.newArrayListWithExpectedSize(1);
        }

        //获取渠道权限
        AgentDto agentDto = agentDtos1.stream().findFirst().orElse(null);
        if(agentDto != null){
            //返回所有代理商
            if(agentDto.getVisableType() == 2){

                SysAgentQueryListReq usableListReq = new SysAgentQueryListReq();
                if(StringUtils.isNotEmpty(req.getAgentName())){
                    usableListReq.setGroupName(req.getAgentName());
                }
                usableListReq.setPageNo(1);
                usableListReq.setPageSize(100);
                usableListReq.setStatus(1);
                usableListReq.setCheckStatus(3);

                PageResponse<SysAgentQueryListDTO> listResult = sysAgentService.queryAgentList(usableListReq, null);
                if(listResult != null){
                    List<AgentDto> agentDtos = listResult.getRecords().stream().map(entity -> {
                        AgentDto dto = new AgentDto();
                        dto.setId(entity.getId());
                        dto.setAgentName(entity.getGroupCnName());
                        //加辐后的价格：成本价+代理加辐费
                        dto.setPrice(Objects.isNull(agentDto.getPrice()) ? BigDecimal.ZERO : agentDto.getPrice()
                                .add(Objects.isNull(agentDto.getAgentFee()) ? BigDecimal.ZERO : agentDto.getAgentFee()));

                        //预定服务费
                        if(agentDto.getReserveChargeType() == null){
                            dto.setAgentFee(BigDecimal.ZERO);
                        }else if(agentDto.getReserveChargeType() == 1){
                            dto.setAgentFee(agentDto.getReserveCharge());
                        }else {
                            dto.setAgentFee(agentDto.getReserveCharge() == null ? BigDecimal.ZERO : NumberUtil.getDecimalPercent(agentDto.getPrice().multiply(agentDto.getReserveCharge()).multiply(new BigDecimal(0.01))));
                        }
                        return dto;
                    }).collect(Collectors.toList());
                   return agentDtos;
                }else {
                    return Lists.newArrayListWithExpectedSize(1);
                }
            }
        }
        return Lists.newArrayListWithExpectedSize(1);
    }

    @Override
    public CustomDto getCustomSelLine(Long productId, Integer agent, Long userId, Long agencyId) {
        List<CustomDto> list = null;
        if(agent == 2){
            //代理商
            list = localFunProductSaleStrategyMapper.getAgentCustomSelLine(productId,LocalDate.now());
            if(CollectionUtils.isEmpty(list)){
                return new CustomDto();
            }
            CustomDto customDto = list.stream().filter(entity -> agencyId.equals(entity.getCustomId())).findFirst().orElse(null);
            if(customDto != null){
                if(customDto.getVisableType() == 2){
                    //代表所有代理商
                    customDto.setCustomId(2L);
                    customDto.setCustomName("所有代理商");
                    return customDto;
                }
                return customDto;
            }
        }else {
            //自营
            list = localFunProductSaleStrategyMapper.getCustomSelLine(productId,LocalDate.now());
            if(CollectionUtils.isEmpty(list)){
                return new CustomDto();
            }
            CustomDto customDto = list.stream().findFirst().orElse(null);
            if(customDto != null){
                if(customDto.getVisableType() == 2){
                    //代表所有部门
                    customDto.setCustomId(1L);
                    customDto.setCustomName("所有部門");
                    return customDto;
                }
                if(customDto.getVisableType() == 3){
                    //人員
                    CustomDto customDto1 = list.stream().filter(entity -> entity.getCustomId() != null && entity.getCustomId().equals(userId)).findFirst().orElse(null);
                    if(customDto1 != null){
                        return customDto1;
                    }else {
                        //部門
                        UserDTO userDTO = iSysUserService.queryCacheUser(userId);
                        CustomDto customDto2 = list.stream().filter(entity -> entity.getCustomId() != null && entity.getCustomId().equals(userDTO.getDeptId())).findFirst().orElse(null);
                        if(customDto2 != null){
                            return customDto2;
                        }
                    }
                }
            }
        }
        return new CustomDto();
    }

    /**
     * 校验该产品用户是否设置产品加辐费
     * @param relId
     * @param allAttrsPriceList
     */
    protected void checkUserCandidate(Long relId, List<LocalFunAddPriceDTO> allAttrsPriceList) {
        if(CollectionUtils.isNotEmpty(allAttrsPriceList)){
            LocalFunAddPriceDTO localFunAddPriceDTO = allAttrsPriceList.stream().findFirst().orElse(null);
            if(localFunAddPriceDTO != null){
                if(localFunAddPriceDTO.getVisableType() == 3){
                    if(relId == null){
                        throw new BusinessException(SystemError.LOCAL_FUN_18020);
                    }
                    List<String> relationIds = getUserIdsByUserId(relId);
                    allAttrsPriceList = allAttrsPriceList.stream().filter(entity->relationIds.contains(entity.getRelationId())).collect(Collectors.toList());
                }
            }
        }
        if(CollectionUtils.isEmpty(allAttrsPriceList)){
            throw new BusinessException(SystemError.LOCAL_FUN_18026);
        }
    }

    /**
     * 構建線下自營渠道 價格
     * @param attrId1
     * @param attrId2
     * @param priceRemainder
     * @param allAttrsPriceList
     * @param departureDate
     * @param relId
     */
    protected void buildOfflinePriceInfo(Long attrId1, Long attrId2, LocalFunPriceRemainderDTO priceRemainder, List<LocalFunAddPriceDTO> allAttrsPriceList, LocalDate departureDate, Long relId) {
        //不指定規格，默認查詢最小價格
        if(attrId1 == null && attrId2 == null){
            LocalFunAddPriceDTO minPriceDto = allAttrsPriceList.stream().min(Comparator.comparing(LocalFunAddPriceDTO::getCostAndFee)).get();
            if(minPriceDto != null){
                priceRemainder.setCostPrice(minPriceDto.getCostPrice());
                priceRemainder.setExchangeRate(minPriceDto.getExchangeRate());
                priceRemainder.setPrice(Objects.isNull(minPriceDto.getCostAndFee()) ? null :NumberUtil.getDecimalPercent(minPriceDto.getCostAndFee()));
                priceRemainder.setSolidNumber(querySolidNumber(minPriceDto,departureDate));
                return;
            }
        }

        //構建指定規格價格
        //構建指定規格價格
        LocalFunAddPriceDTO specialPriceDto = null;
        if(relId == null || relId == 1L){
            specialPriceDto = allAttrsPriceList.stream().filter(entity -> {
                Boolean exactly = false;
                if (attrId1 != null && attrId2 != null) {
                    exactly = entity.getAttr1Id().equals(attrId1) && entity.getAttr2Id().equals(attrId2);
                }
                if (attrId1 != null && attrId2 == null) {
                    exactly = entity.getAttr1Id().equals(attrId1);
                }
                return exactly;
            }).findFirst().orElse(null);
        }else {
            LocalFunAddPriceDTO localFunAddPriceDTO = allAttrsPriceList.stream().findFirst().orElse(null);
            if(localFunAddPriceDTO != null){
                if(localFunAddPriceDTO.getVisableType() == 2){
                    specialPriceDto = allAttrsPriceList.stream().filter(entity -> {
                        Boolean exactly = false;
                        if (attrId1 != null && attrId2 != null) {
                            exactly = entity.getAttr1Id().equals(attrId1) && entity.getAttr2Id().equals(attrId2);
                        }
                        if (attrId1 != null && attrId2 == null) {
                            exactly = entity.getAttr1Id().equals(attrId1);
                        }
                        return exactly;
                    }).findFirst().orElse(null);
                }else {
                    specialPriceDto = allAttrsPriceList.stream().filter(entity -> {
                        Boolean exactly = false;
                        if (attrId1 != null && attrId2 != null) {
                            exactly = entity.getAttr1Id().equals(attrId1) && entity.getAttr2Id().equals(attrId2);
                        }
                        if (attrId1 != null && attrId2 == null) {
                            exactly = entity.getAttr1Id().equals(attrId1);
                        }
                        return exactly;
                    }).filter(en -> relId.equals(en.getRelationId())).findFirst().orElse(null);
                }
            }
        }
        if(specialPriceDto != null){
            priceRemainder.setCostPrice(specialPriceDto.getCostPrice());
            priceRemainder.setExchangeRate(specialPriceDto.getExchangeRate());
            priceRemainder.setPrice(NumberUtil.getDecimalPercent(specialPriceDto.getCostAndFee()));
            priceRemainder.setSolidNumber(querySolidNumber(specialPriceDto, departureDate));
            return;
        }
    }

    /**
     * 获取余票
     * @param specialPriceDto
     * @param departureDate
     * @return
     */
    private Integer querySolidNumber(LocalFunAddPriceDTO specialPriceDto, LocalDate departureDate) {
        //1：限购售额
        if(specialPriceDto.getIsLimit() != null && specialPriceDto.getLimitNum() != null && specialPriceDto.getIsLimit() == 1){
            //今日可售額
            Integer limitNum = specialPriceDto.getLimitNum();
            //產品总庫存
            Integer solidStock = specialPriceDto.getSolidStock();

            //今日可售額 大於庫存，余票=总庫存-產品已售額
            if(limitNum > solidStock){
                int surplusNumber = saleRecordMapper.selectSoldStockCount(specialPriceDto.getProductId());
                return solidStock-surplusNumber;
            }else {
                if(limitNum == null || limitNum == 0){
                    throw new BusinessException(SystemError.SHIP_PRODUCT_11051);
                }
                //餘票=今日可售額-今日已售額
                int soldStockCount = saleRecordMapper.selectTodaySoldStockCount(specialPriceDto.getProductId(),Date.from(departureDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
                return limitNum -soldStockCount;
            }
        }
        //2.不限售額，余票=总庫存-產品已售額
        else {
            Integer solidStock = specialPriceDto.getSolidStock();
            //餘票=庫存-產品已售額
            int surplusNumber = saleRecordMapper.selectSoldStockCount(specialPriceDto.getProductId());
            return solidStock-surplusNumber;
        }
    }


    private List<String> getUserIdsByUserId(Long id) {
        List<Long> longs = iSysDepartmentService.queryIdsByUserId(id);
        longs.add(id);
        String stringBuffer = "";
        for (Long aLong : longs) {
            stringBuffer += aLong.toString() + ",";
        }
        if (!"".equals(stringBuffer)) {
            stringBuffer = stringBuffer.substring(0, stringBuffer.length() - 1);
        }
        return Lists.newArrayList(stringBuffer.split(","));
    }

    /**
     * 設置成本有效期和幅加策略有效期
     * @param localFunResourceDTOList
     */
    private void setValidateTime(List<LocalFunDyTicketProductDTO> localFunResourceDTOList) {
        localFunResourceDTOList.forEach(entity->{
            //成本有效期 最小~最大
            LocalFunProductCostStrategyVaildDate costValidDate = costStrategyVaildDateMapper.selectValidteTime(entity.getId());
            if(costValidDate != null){
                entity.setCostValidStartTime(costValidDate.getTimeBegin());
                entity.setCostValidEndTime(costValidDate.getTimeEnd());
            }
            //幅加有效期 最小~最大
            LocalFunProductSaleStrategyVaildDate saleValidDate = localFunProductSaleStrategyVaildDateMapper.selectValidteTime(entity.getId());
            if(saleValidDate != null){
                entity.setSaleValidStartTime(saleValidDate.getTimeBegin());
                entity.setSaleValidEndTime(saleValidDate.getTimeEnd());
            }
        });
    }

    /**
     * 過濾不滿足條件的產品
     * @param localFunDyTicketProductDTOS
     * @param userId
     */
    private List<LocalFunDyTicketProductDTO> productPrivilegeVisitable(List<LocalFunDyTicketProductDTO> localFunDyTicketProductDTOS, Long userId) {
        //产品开售过滤
        LocalDate nowDate = LocalDate.now();

        //1.过滤出产品开售日期范围包括当天的产品
        localFunDyTicketProductDTOS = localFunDyTicketProductDTOS.stream().filter(entity->
            nowDate.compareTo(entity.getStartSaleTimeBegin()) >= 0 &&
                    nowDate.compareTo(entity.getStartSaleTimeEnd()) <= 0
        //2.过滤出产品规格成本有效期范围在当天的产品
        ).filter(entity->entity != null && nowDate.compareTo(entity.getCostValidStartTime()) >= 0 &&
                nowDate.compareTo(entity.getCostValidEndTime()) <= 0
        //3.过滤出产品规格幅加策略有效期范围在当天的产品
        ).filter(entity->entity != null && nowDate.compareTo(entity.getSaleValidStartTime()) >= 0 &&
                nowDate.compareTo(entity.getSaleValidEndTime()) <= 0
        //4.用户已授权用户可见，其他权限暂未处理
        ).filter(entity->checkUserVisiable(entity,userId)).collect(Collectors.toList());

        //5.设置产品价格：成本价+幅加费
        addFee(userId, localFunDyTicketProductDTOS, nowDate);

        return localFunDyTicketProductDTOS;
    }

    /**
     * 動態套票產品列表-查詢條件
     * @param req
     * @return
     */
    private QueryWrapper<LocalFunProduct> queryParam(LocalFunDyTicketProductReq req) {
        QueryWrapper<LocalFunProduct> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(req.getCityName())){
            queryWrapper.lambda().like(LocalFunProduct::getCityName,req.getCityName());
        }
        if(req.getFunId() != null){
            queryWrapper.lambda().eq(LocalFunProduct::getFunType,req.getFunId());
        }
        //上架
        queryWrapper.lambda().eq(LocalFunProduct::getStatus, 1);
        return queryWrapper;
    }

    /**
     * 设置产品价格：成本价+幅加费
     * @param userId
     * @param productDtoList
     * @param nowDate
     */
    private void addFee(Long userId, List<LocalFunDyTicketProductDTO> productDtoList, LocalDate nowDate) {
        productDtoList.forEach(entity->{
            LocalFunProductCostReq costReq = new LocalFunProductCostReq();
            costReq.setProductId(entity.getId());
            costReq.setQueryDate(nowDate);
            costReq.setUserId(userId);
            costReq.setChannelType(1);
            List<LocalFunProductCostDTO> productCostList = iLocalFunCostPriceService.getProductCostList(costReq);

            //設置產品規格信息
            if(CollectionUtils.isNotEmpty(productCostList)){
                List<ProductAttrItemDTO> attrItemDTOList = productCostList.stream().map(cost->{
                    ProductAttrItemDTO attrItemDTO = new ProductAttrItemDTO();
                    attrItemDTO.setAttrId1(cost.getAttr1Id());
                    attrItemDTO.setAttrId2(cost.getAttr2Id());
                    attrItemDTO.setItemName(cost.getAttr2Name());
                    attrItemDTO.setPrice(NumberUtil.getDecimalPercent(cost.getPrice()));
                    attrItemDTO.setStartTime(cost.getTimeBegin());
                    attrItemDTO.setEndTime(cost.getTimeEnd());
                    attrItemDTO.setIntendedUser(entity.getIntendedUser());
                    attrItemDTO.setProductId(entity.getId());
                    return attrItemDTO;
                }).collect(Collectors.toList());

                entity.setItemDTOList(attrItemDTOList);
            }
        });
    }

    /**
     * 校验用户可见
     * @param entity
     * @param id 用戶ID
     * @return
     */
    private boolean checkUserVisiable(LocalFunDyTicketProductDTO entity, Long id) {
        Result<Long> result = getExactStrategyId(LocalDate.now(), entity.getId());
        QueryWrapper<LocalFunProductChannelOffline> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(LocalFunProductChannelOffline::getStrategyId,result.getData());
        List<LocalFunProductChannelOffline> channelOffLines = localFunProductChannelOfflineMapper.selectList(queryWrapper);

        //暂时只考虑自营渠道
        if(CollectionUtils.isNotEmpty(channelOffLines)){
            //1、自营 2、代理  取自营渠道权限
            LocalFunProductChannelOffline channelOffline = channelOffLines.stream().filter(en ->
                    ProductCenterEnum.SEL_CUSTOM_CHANNEL.getChannelCode().equals(en.getChannelType())).findFirst().orElse(null);

            if(channelOffline != null){
                Integer visableType = channelOffline.getVisableType();
                // 1 禁止自营   所有用户不可见
                if(ProductCenterEnum.SEL_CUSTOM_FORBID == visableType){
                    return false;
                }
                //2 所有部门   所有部门可见
                else if(ProductCenterEnum.ALL_DEPT_SALE == visableType){
                    return true;
                }
                //2 指定人员、部门可见
                else if(ProductCenterEnum.PERSONAL_SALE == visableType){
                    QueryWrapper<LocalFunProductChannelOfflineSelfCustom> customQueryWrapper = new QueryWrapper<>();
                    //人员 checkType 1:部门 2：员工
                    customQueryWrapper.lambda().eq(LocalFunProductChannelOfflineSelfCustom::getOfflineId,channelOffline.getId());
                    List<LocalFunProductChannelOfflineSelfCustom> selfCustomList = localFunProductChannelOfflineSelfCustomMapper.selectList(customQueryWrapper);

                    //校验 自营渠道，当前用户匹配指定部门、人员可见
                    if(CollectionUtils.isNotEmpty(selfCustomList)){
                        SysDepartmentDTO sysDepartmentDTO = iSysDepartmentService.queryByUserId(id);
                        return selfCustomList.stream().anyMatch(en->en.getRelationId().equals(id)
                                || en.getRelationId().equals(sysDepartmentDTO !=null ? sysDepartmentDTO.getId() : -99));
                    }
                }
            }
        }
        return false;
    }

    public static final Map<Integer,Map<Integer,List<LocalDate>>> validateTimeMap = Maps.newConcurrentMap();
    /**
     * 封装加幅有效期
     * @param localFunProductReq
     * @param validDateDTOList
     * @param saleStrategy
     * @param offlineCanalListDTOList
     * @param onlineSelfListDTOList
     */
    private void addValidDateToDTO(LocalFunProductReq localFunProductReq, List<VaildDateDTO> validDateDTOList, LocalFunProductSaleStrategy saleStrategy,
                                   List<OfflineCanalListDTO> offlineCanalListDTOList, List<OnlineSelfListDTO> onlineSelfListDTOList) throws ParseException{
        //获取加幅策略有效期结果集
        QueryWrapper<LocalFunProductSaleStrategyVaildDate> vaildDateQueryWrapper = new QueryWrapper<>();
        vaildDateQueryWrapper.eq("strategy_id",saleStrategy.getId());
        List<LocalFunProductSaleStrategyVaildDate> vaildDateList = localFunProductSaleStrategyVaildDateMapper.selectList(vaildDateQueryWrapper);

        if(CollectionUtils.isEmpty(vaildDateList)) {
            return;
        }
        //查询条件：年-月
        int year = Integer.parseInt(localFunProductReq.getYear());
        int month = Integer.parseInt(localFunProductReq.getMonth());

        validateTimeMap.clear();
        //缓存日期 - 解决时间段跨月份，月份数据缺失的问题
        cacheValidate(validateTimeMap,vaildDateList);

        if(validateTimeMap.get(year) == null){
            return;
        }
        List<LocalDate> dateTimeList = validateTimeMap.get(year).get(month);
        if(CollectionUtils.isNotEmpty(dateTimeList)){
            dateTimeList.forEach(localDateTime->{
                VaildDateDTO vaildDateDTO = new VaildDateDTO();
                vaildDateDTO.setDate(DateUtil.fmtLocalDate(localDateTime,"yyyy-MM-dd"));
                vaildDateDTO.setOnlineSelfListDTOList(onlineSelfListDTOList);
                vaildDateDTO.setOfflineCanalListDTOList(offlineCanalListDTOList);
                validDateDTOList.add(vaildDateDTO);
            });
        }
    }

    /**
     * 缓存日期 - 解决时间段跨月份，月份数据缺失的问题
     *
     * @param validateMap
     * @param vaildDateList
     */
    private void cacheValidate(Map<Integer,Map<Integer, List<LocalDate>>> validateMap, List<LocalFunProductSaleStrategyVaildDate> vaildDateList) {
        vaildDateList.forEach(entity->{
            List<LocalDate> dateTimeList = Stream.iterate(entity.getTimeBegin(), date -> date.plusDays(1))
                    .limit(ChronoUnit.DAYS.between(entity.getTimeBegin(), entity.getTimeEnd()))
                    .collect(Collectors.toList());
            dateTimeList.add(entity.getTimeEnd());

            Map<Integer, List<LocalDate>> timeYearMap = dateTimeList.stream().collect(Collectors.groupingBy(LocalDate::getYear));
            timeYearMap.forEach((key,val)->{
                Map<Integer, List<LocalDate>> timeMonthMap = val.stream().collect(Collectors.groupingBy(LocalDate::getMonthValue));
                validateMap.put(key,timeMonthMap);
            });
        });
    }

    /**
     * 获取日期列表
     * @param fixStartDate
     * @param fixEndDate
     * @param startDate
     * @param endDate
     * @return
     */
    private List<String> getBetweenDateList(Date fixStartDate, Date fixEndDate, Date startDate, Date endDate) {
        if(fixStartDate.getTime() > startDate.getTime() && endDate.getTime() > fixEndDate.getTime()){
            return obtainBetweenDateList(fixStartDate.getTime(), fixEndDate.getTime());

        }else if(fixStartDate.getTime() > startDate.getTime() && endDate.getTime() < fixEndDate.getTime()){
            //01-7号-有效期
            return obtainBetweenDateList(fixStartDate.getTime(), endDate.getTime());
        }else if(fixStartDate.getTime() < startDate.getTime() && endDate.getTime() > fixEndDate.getTime()){
            //开始有效期-31号
            return obtainBetweenDateList(startDate.getTime(), fixEndDate.getTime());
        }else if (fixStartDate.getTime() < startDate.getTime() && endDate.getTime() < fixEndDate.getTime()){
            //开始有效期-有效期结束日期
            return obtainBetweenDateList(startDate.getTime(), endDate.getTime());
        }
        return Lists.newArrayList();
    }

    /**
     * 获取两个日期之间的日期列表
     * @param start
     * @param endTime
     * @return
     */
    public static List<String>  obtainBetweenDateList(Long start,Long endTime) {
        Long oneDay = 1000 * 60 * 60 * 24l;

        List<String> dateList = Lists.newLinkedList();
        Long time = start;
        while (time <= endTime) {
            Date d = new Date(time);
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            dateList.add(df.format(d));
            time += oneDay;
        }
        return dateList;
    }
    /**
     * 封装第三方平台加幅信息结果集
     * @param onlineSelfListDTOList
     * @param scenicProductSaleStrategy
     */
    private void addOnlineOtherPlatformToOnlineDTO(List<OnlineSelfListDTO> onlineSelfListDTOList, LocalFunProductSaleStrategy scenicProductSaleStrategy) {
        //查询第三方渠道
        QueryWrapper<LocalFunProductChannelOnlineThirdPlatform> thirdPlatformQueryWrapper = new QueryWrapper<>();
        thirdPlatformQueryWrapper.eq("is_deleted",0);
        thirdPlatformQueryWrapper.eq("product_id",scenicProductSaleStrategy.getProductId());
        List<LocalFunProductChannelOnlineThirdPlatform> thirdPlatformList = channelOnlineThirdPlatformMapper.selectList(thirdPlatformQueryWrapper);
        if(CollectionUtils.isNotEmpty(thirdPlatformList)){
            for(LocalFunProductChannelOnlineThirdPlatform thirdPlatform : thirdPlatformList){
                OnlineSelfListDTO onlineSelfListDTO = new OnlineSelfListDTO();
                //1.设置渠道名称
                onlineSelfListDTO.setCanal(thirdPlatform.getPlatformName());
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(thirdPlatform.getAdjustType())){
                    onlineSelfListDTO.setAddSize(Objects.isNull(thirdPlatform.getAmount()) ? "" : thirdPlatform.getAmount().toString() + " " + "HKD");
                }else {
                    onlineSelfListDTO.setAddSize(Objects.isNull(thirdPlatform.getPercent()) ? "" : thirdPlatform.getPercent().toString() + "%");
                }

                //2.设置加幅字符串20HKD
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(thirdPlatform.getAdjustType())){
                    onlineSelfListDTO.setAddSize(Objects.isNull(thirdPlatform.getAmount()) ? "" : thirdPlatform.getAmount().toString() + " " +"HKD");
                }else {
                    onlineSelfListDTO.setAddSize(Objects.isNull(thirdPlatform.getPercent()) ? "" : thirdPlatform.getPercent().toString() + "%");
                }

                //3.设置每日可售数；是否设置限制
                if(ProductCenterEnum.IS_NOT_LIMIT.getChannelCode().equals(thirdPlatform.getIsLimit())){
                    onlineSelfListDTO.setLimitNum(IS_LIMIT);
                }else {
                    onlineSelfListDTO.setLimitNum(Objects.isNull(thirdPlatform.getLimitNum()) ? "" : thirdPlatform.getLimitNum().toString());
                }

                //4.今日已售数  条件：线上、第三方平台
                List<LocalFunProductSaleRecord> currentSaleRecords = localFunProductSaleRecordMapper.getCurrentSaleRecord(thirdPlatform.getProductId(),3,null,1);
                if(CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(LocalFunProductSaleRecord::getSoldNumber).sum();
                    onlineSelfListDTO.setSoldToday(sum);
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(thirdPlatform.getIsLimit())){
                        //剩余可售数
                        onlineSelfListDTO.setSurplusStock(StringUtils.isEmpty(onlineSelfListDTO.getLimitNum()) ? 0 : Integer.valueOf(onlineSelfListDTO.getLimitNum())-sum);
                    }
                }else {
                    onlineSelfListDTO.setSoldToday(0);
                    onlineSelfListDTO.setSurplusStock(StringUtils.isEmpty(onlineSelfListDTO.getLimitNum()) ? 0 : Integer.valueOf(onlineSelfListDTO.getLimitNum()));
                }
                onlineSelfListDTOList.add(onlineSelfListDTO);
            }
        }
    }

    /**
     * 封装官方平台加幅信息结果集
     * @param onlineSelfListDTOList
     * @param scenicProductSaleStrategy
     */
    private void addOnlineOfficePlatformToOnlineDTO(List<OnlineSelfListDTO> onlineSelfListDTOList, LocalFunProductSaleStrategy scenicProductSaleStrategy) {
        QueryWrapper<LocalFunProductChannelOnlineSelfPlatform> platformQueryWrapper = new QueryWrapper<>();
        platformQueryWrapper.eq("is_deleted",0);
        platformQueryWrapper.eq("strategy_id",scenicProductSaleStrategy.getId());
        List<LocalFunProductChannelOnlineSelfPlatform> selfPlatformList = channelOnlineSelfPlatformMapper.selectList(platformQueryWrapper);

        if(CollectionUtils.isNotEmpty(selfPlatformList)){
            for(LocalFunProductChannelOnlineSelfPlatform selfPlatform : selfPlatformList){
                OnlineSelfListDTO onlineSelfListDTO = new OnlineSelfListDTO();

                //1.设置渠道名称
                if(selfPlatform.getChannelId() == ChannelMainData.APP_H5.getId()){
                    onlineSelfListDTO.setCanal(ChannelMainData.APP_H5.getMsg());
                }else if(selfPlatform.getChannelId() == ChannelMainData.CHINA_TRAVEL.getId()){
                    onlineSelfListDTO.setCanal(ChannelMainData.CHINA_TRAVEL.getMsg());
                }

                //2.设置加幅字符串20HKD
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(selfPlatform.getAdjustType())){
                    onlineSelfListDTO.setAddSize(Objects.isNull(selfPlatform.getAmount()) ? "" : selfPlatform.getAmount().toString() + " " +"HKD");
                }else {
                    onlineSelfListDTO.setAddSize(selfPlatform.getPercent().toString() + "%");
                }

                //3.设置今日可售数；是否设置限制
                if(ProductCenterEnum.IS_NOT_LIMIT.equals(selfPlatform.getIsLimit())){
                    onlineSelfListDTO.setLimitNum(IS_LIMIT);
                }else {
                    onlineSelfListDTO.setLimitNum(Objects.isNull(selfPlatform.getLimitNum()) ? "" : selfPlatform.getLimitNum().toString());
                }

                //4.今日已售数  条件：线上、第三方平台
                List<LocalFunProductSaleRecord> currentSaleRecords = localFunProductSaleRecordMapper.getCurrentSaleRecord(selfPlatform.getProductId(),4,null,1);
                if(CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(LocalFunProductSaleRecord::getSoldNumber).sum();
                    onlineSelfListDTO.setSoldToday(sum);
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(selfPlatform.getIsLimit())){
                        //剩余可售数
                        onlineSelfListDTO.setSurplusStock(StringUtils.isEmpty(onlineSelfListDTO.getLimitNum()) ? 0 : Integer.valueOf(onlineSelfListDTO.getLimitNum())-sum);
                    }
                }else {
                    onlineSelfListDTO.setSoldToday(0);
                    onlineSelfListDTO.setSurplusStock(StringUtils.isEmpty(onlineSelfListDTO.getLimitNum()) ? 0 : Integer.valueOf(onlineSelfListDTO.getLimitNum()));
                }
                onlineSelfListDTOList.add(onlineSelfListDTO);
            }
        }
    }

    private void addAgentStrategyToOffLineDTO(List<OfflineCanalListDTO> offlineCanalListDTOList, LocalFunProductChannelOffline channelOffLine) {
        QueryWrapper<LocalFunProductChannelOfflineAgentCustom> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted",0);
        queryWrapper.eq("product_id",channelOffLine.getProductId());
        List<LocalFunProductChannelOfflineAgentCustom> agentCustoms = localFunProductChannelOfflineAgentCustomMapper.selectList(queryWrapper);
        if(CollectionUtils.isNotEmpty(agentCustoms)){
            for(LocalFunProductChannelOfflineAgentCustom custom : agentCustoms){
                OfflineCanalListDTO offlineCanalListDTO = new OfflineCanalListDTO();
                //1.设置指定代理商名称
                offlineCanalListDTO.setCanal(custom.getAgentName());

                //2.设置加幅字符串 20HKD；加幅类型: 金额 1，百分比 2
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(custom.getAdjustType())){
                    offlineCanalListDTO.setAddSize(custom.getAmount().toString() + " " +"HKD");
                } else{
                    offlineCanalListDTO.setAddSize(custom.getPercent().toString() + "%");
                }

                //3.设置今日可售数量；是否设置限购
                if(ProductCenterEnum.IS_NOT_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                    offlineCanalListDTO.setLimitNum(IS_LIMIT);
                }else {
                    offlineCanalListDTO.setLimitNum(Objects.isNull(custom.getLimitNum())?null:custom.getLimitNum().toString());
                }
                if(channelOffLine.getVisableType() == 2){
                    offlineCanalListDTO.setCanal("所有代理");
                }

                //4.今日已售数  条件：线下、代理商
                List<LocalFunProductSaleRecord> currentSaleRecords = localFunProductSaleRecordMapper.getCurrentSaleRecord(custom.getProductId(),2,null,2);
                if(CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(LocalFunProductSaleRecord::getSoldNumber).sum();
                    offlineCanalListDTO.setSoldToday(sum+"");
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                        //剩余可售数
                        offlineCanalListDTO.setSurplusStock(String.valueOf(Integer.valueOf(offlineCanalListDTO.getLimitNum())-sum));
                    }
                }else {
                    offlineCanalListDTO.setSoldToday(0+"");
                    offlineCanalListDTO.setSurplusStock(offlineCanalListDTO.getLimitNum());
                }
                offlineCanalListDTOList.add(offlineCanalListDTO);
            }
        }

    }

    /**
     * 添加线下自营加幅信息列表-提供详情日历展示列表
     * @param offlineCanalListDTOList
     * @param channelOffLine
     */
    private void addSelCustomStrategyToOffLineDTO(List<OfflineCanalListDTO> offlineCanalListDTOList, LocalFunProductChannelOffline channelOffLine) {
        QueryWrapper<LocalFunProductChannelOfflineSelfCustom> customQueryWrapper = new QueryWrapper<>();
        customQueryWrapper.eq("is_deleted",0);
        customQueryWrapper.eq("product_id",channelOffLine.getProductId());
        //查询出线下渠道集合
        List<LocalFunProductChannelOfflineSelfCustom> channelOfflineSelfCustoms = localFunProductChannelOfflineSelfCustomMapper.selectList(customQueryWrapper);

        if(CollectionUtils.isNotEmpty(channelOfflineSelfCustoms)){
            for(LocalFunProductChannelOfflineSelfCustom custom : channelOfflineSelfCustoms){
                if(custom.getCheckType() == null){
                    continue;
                }
                OfflineCanalListDTO offlineCanalListDTO = new OfflineCanalListDTO();

                //1.设置渠道名称：部门名称/人员名称 ；勾选人： 2 勾选部门： 1
                if(custom.getRelationId() != null && custom.getRelationId() != 0L){
                    if(ProductCenterEnum.DEPT_CHOOSE != custom.getCheckType()){
                        SysDepartmentDTO sysDepartmentDTO = departmentService.queryByUserId(custom.getRelationId());
                        offlineCanalListDTO.setCanal(sysDepartmentDTO.getTitle());
                    }else{
                        UserDTO userDTO = iSysUserService.loadUserByParam(custom.getRelationId(), 1);
                        offlineCanalListDTO.setCanal(userDTO.getUsername());
                    }
                }

                //2.设置加幅字符串 20HKD；加幅类型: 金额 1，百分比 2
                if(ProductCenterEnum.AMOUNT.getChannelCode().equals(custom.getAdjustType())){
                    offlineCanalListDTO.setAddSize(custom.getAmount().toString() + " " +"HKD");
                } else {
                    offlineCanalListDTO.setAddSize(custom.getPercent().toString() + "%");
                }

                //3.设置每日可售数；是否设置限购
                if(ProductCenterEnum.IS_NOT_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                    offlineCanalListDTO.setLimitNum(IS_LIMIT);
                    offlineCanalListDTO.setSurplusStock("-");
                }else {
                    offlineCanalListDTO.setLimitNum(Objects.isNull(custom.getLimitNum())?null:custom.getLimitNum().toString());
                }

                if(channelOffLine.getVisableType() == 2){
                    offlineCanalListDTO.setCanal("所有部門");
                }

                //4.今日已售数  条件：线下、自营
                List<LocalFunProductSaleRecord> currentSaleRecords = localFunProductSaleRecordMapper.getCurrentSaleRecord(custom.getProductId(),1,custom.getCheckType(),2);
                if(CollectionUtils.isNotEmpty(currentSaleRecords)){
                    //今日已售数
                    int sum = currentSaleRecords.stream().mapToInt(LocalFunProductSaleRecord::getSoldNumber).sum();
                    offlineCanalListDTO.setSoldToday(sum+"");
                    if(ProductCenterEnum.IS_LIMIT.getChannelCode().equals(custom.getIsLimit())){
                        //剩余可售数
                        offlineCanalListDTO.setSurplusStock(String.valueOf(Integer.valueOf(offlineCanalListDTO.getLimitNum())-sum));
                    }
                }else {
                    offlineCanalListDTO.setSoldToday(0+"");
                    offlineCanalListDTO.setSurplusStock(offlineCanalListDTO.getLimitNum());
                }
                offlineCanalListDTOList.add(offlineCanalListDTO);
            }
        }
    }

    private void warpperProductBaseInfo(LocalFunProductDetailDTO scenicProductDetailDTO, LocalFunProduct scenicProduct) {
        if(scenicProduct != null){
            LocalFunProductListDTO scenicProductListDTO = EntityUtil.copy(scenicProduct, LocalFunProductListDTO.class);
            if((scenicProduct.getReserveChargeType() != null) && scenicProduct.getReserveChargeType() == 1){
                //类型是加数值
                scenicProductListDTO.setReserveCharge(scenicProduct.getReserveCharge().toString() + "HKD");
            }else if((scenicProduct.getReserveChargeType() != null) && scenicProduct.getReserveChargeType() == 2){
                //类型是百分比
                scenicProductListDTO.setReserveCharge(scenicProduct.getReserveCharge().toString() + "%");
            }
            if((scenicProduct.getCtsChargeType() != null) && scenicProduct.getCtsChargeType() == 1){
                //类型是加数值
                scenicProductListDTO.setCtsCharge(scenicProduct.getCtsCharge().toString() + "HKD");
            }else if((scenicProduct.getCtsChargeType() != null) && scenicProduct.getCtsChargeType() == 2){
                //类型是百分比
                scenicProductListDTO.setCtsCharge(scenicProduct.getCtsCharge().toString() + "%");
            }
            scenicProductDetailDTO.setScenicProductListDTO(scenicProductListDTO);
        }
    }

    /**
     * 设置渠道加幅
     * @param id                                产品增幅策略ID
     * @param localFunProductSaleStrategyReq    请求入参
     * @param productId
     * @param userId
     */
    private void addChannelSale(Long id, LocalFunProductSaleStrategyReq localFunProductSaleStrategyReq, Long productId, Long userId) {
        ChannelSaleReq channelSaleReq = localFunProductSaleStrategyReq.getChannelSaleReq();

        //1.新增线下自营渠道
        addOffLineSelCustom(channelSaleReq,productId,userId,id);

        //2.新增线下代理商
        addOffLineAgent(channelSaleReq,productId,userId,id);

        //3.新增线上官方平台
        addOnLineOfficePlatForm(channelSaleReq,productId,userId,id);

        //4.新增线上第三方平台
        addOnLineOtherPlatform(channelSaleReq,productId,userId,id);

    }

    /**
     * 新增线上第三方平台
     * @param channelSaleReq    数据源
     * @param productId         产品ID
     * @param userId            用户ID
     * @param id                产品增幅策略ID
     */
    private void addOnLineOtherPlatform(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long id) {
        List<LocalFunProductChannelOnlineThirdPlatformReq> LocalFunProductChannelOnlineThirdPlatformReqList = channelSaleReq.getLocalFunProductChannelOnlineThirdPlatformReqList();
        if (LocalFunProductChannelOnlineThirdPlatformReqList != null) {
            for (LocalFunProductChannelOnlineThirdPlatformReq req1 : LocalFunProductChannelOnlineThirdPlatformReqList) {
                LocalFunProductChannelOnlineThirdPlatform LocalFunProductChannelOnlineThirdPlatform = new LocalFunProductChannelOnlineThirdPlatform();
                LocalFunProductChannelOnlineThirdPlatform.setProductId(productId);
                LocalFunProductChannelOnlineThirdPlatform.setIsDeleted(0);
                LocalFunProductChannelOnlineThirdPlatform.setStrategyId(id);
                LocalFunProductChannelOnlineThirdPlatform.setCreateId(userId);
                LocalFunProductChannelOnlineThirdPlatform.setPlatformId(req1.getPlatformId());
                LocalFunProductChannelOnlineThirdPlatform.setPlatformName(req1.getPlatformName());
                LocalFunProductChannelOnlineThirdPlatform.setGmtCreate(LocalDateTime.now());
                if (req1.getAdjustType() == 1) {
                    LocalFunProductChannelOnlineThirdPlatform.setAdjustType(1);
                    LocalFunProductChannelOnlineThirdPlatform.setAmount(req1.getAmount());
                } else if (req1.getAdjustType() == 2) {
                    LocalFunProductChannelOnlineThirdPlatform.setAdjustType(2);
                    LocalFunProductChannelOnlineThirdPlatform.setPercent(req1.getPercent());
                } else {
                    break;
                }
                if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                    LocalFunProductChannelOnlineThirdPlatform.setIsLimit(0);
                } else {
                    LocalFunProductChannelOnlineThirdPlatform.setIsLimit(1);
                    LocalFunProductChannelOnlineThirdPlatform.setLimitNum(req1.getLimitNum());
                }
                LocalFunProductChannelOnlineThirdPlatform.setId(SnowflakeIdWorker.nextId());
                channelOnlineThirdPlatformMapper.insert(LocalFunProductChannelOnlineThirdPlatform);
            }
        }
    }

    /**
     * 新增线上官方平台
     * @param channelSaleReq    数据源
     * @param productId         产品ID
     * @param userId            用户ID
     * @param id                产品增幅策略ID
     */
    private void addOnLineOfficePlatForm(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long id) {
        List<LocalFunProductChannelOnlineSelfPlatformReq> LocalFunProductChannelOnlineSelfPlatformReqList = channelSaleReq.getLocalFunProductChannelOnlineSelfPlatformReqList();
        if (LocalFunProductChannelOnlineSelfPlatformReqList != null) {
            for (LocalFunProductChannelOnlineSelfPlatformReq req1 : LocalFunProductChannelOnlineSelfPlatformReqList) {
                LocalFunProductChannelOnlineSelfPlatform LocalFunProductChannelOnlineSelfPlatform = new LocalFunProductChannelOnlineSelfPlatform();
                LocalFunProductChannelOnlineSelfPlatform.setProductId(productId);
                LocalFunProductChannelOnlineSelfPlatform.setStrategyId(id);
                LocalFunProductChannelOnlineSelfPlatform.setCreateId(userId);
                LocalFunProductChannelOnlineSelfPlatform.setChannelId(req1.getChannelId());
                LocalFunProductChannelOnlineSelfPlatform.setIsDeleted(0);
                LocalFunProductChannelOnlineSelfPlatform.setGmtCreate(LocalDateTime.now());
                LocalFunProductChannelOnlineSelfPlatform.setChannelId(req1.getChannelId());
                LocalFunProductChannelOnlineSelfPlatform.setChannelName(req1.getChannelName());
                if (req1.getAdjustType() == 1) {
                    LocalFunProductChannelOnlineSelfPlatform.setAdjustType(1);
                    LocalFunProductChannelOnlineSelfPlatform.setAmount(req1.getAmount());
                } else if (req1.getAdjustType() == 2) {
                    LocalFunProductChannelOnlineSelfPlatform.setAdjustType(2);
                    LocalFunProductChannelOnlineSelfPlatform.setPercent(req1.getPercent());
                } else {
                    break;
                }
                if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                    LocalFunProductChannelOnlineSelfPlatform.setIsLimit(0);
                } else  {
                    LocalFunProductChannelOnlineSelfPlatform.setIsLimit(1);
                    LocalFunProductChannelOnlineSelfPlatform.setLimitNum(req1.getLimitNum());
                }

                LocalFunProductChannelOnlineSelfPlatform.setId(SnowflakeIdWorker.nextId());
                channelOnlineSelfPlatformMapper.insert(LocalFunProductChannelOnlineSelfPlatform);
            }
        }
    }

    /**
     * 新增线下代理商
     * @param channelSaleReq    数据源
     * @param productId         产品ID
     * @param userId            用户ID
     * @param id                产品增幅策略ID
     */
    private void addOffLineAgent(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long id) {
        LocalFunProductAgentReq LocalFunProductAgentReq = channelSaleReq.getLocalFunProductAgentReq();
        if (LocalFunProductAgentReq != null) {
            Long offLineId = SnowflakeIdWorker.nextId();
            LocalFunProductChannelOffline LocalFunProductChannelOffline = new LocalFunProductChannelOffline();
            LocalFunProductChannelOffline.setProductId(productId);
            LocalFunProductChannelOffline.setChannelType(2);
            LocalFunProductChannelOffline.setCreateId(userId);
            LocalFunProductChannelOffline.setIsDeleted(0);
            LocalFunProductChannelOffline.setStrategyId(id);
            //代理商
            LocalFunProductChannelOfflineAgentCustom LocalFunProductChannelOfflineAgentCustom = new LocalFunProductChannelOfflineAgentCustom();
            LocalFunProductChannelOfflineAgentCustom.setProductId(productId);
            LocalFunProductChannelOfflineAgentCustom.setGmtCreate(LocalDateTime.now());
            LocalFunProductChannelOfflineAgentCustom.setCreateId(userId);
            LocalFunProductChannelOfflineAgentCustom.setOfflineId(offLineId);

            switch (LocalFunProductAgentReq.getVisableType()) {
                case 1:
                    saveOffLineChannel(LocalFunProductChannelOffline, LocalFunProductAgentReq.getOfflineAgentId(), offLineId, 1,ProductCenterEnum.AGENT_CUSTOM);
                    break;
                case 2:
                    saveOffLineChannel(LocalFunProductChannelOffline, LocalFunProductAgentReq.getOfflineAgentId(), offLineId, 2,ProductCenterEnum.AGENT_CUSTOM);
                    if (LocalFunProductAgentReq.getAdjustType() == 1) {
                        LocalFunProductChannelOfflineAgentCustom.setAmount(LocalFunProductAgentReq.getAmount());
                        LocalFunProductChannelOfflineAgentCustom.setAdjustType(1);
                    } else if (LocalFunProductAgentReq.getAdjustType() == 2) {
                        LocalFunProductChannelOfflineAgentCustom.setAdjustType(2);
                        LocalFunProductChannelOfflineAgentCustom.setPercent(LocalFunProductAgentReq.getPercent());
                    } else {
                        break;
                    }
                    if (LocalFunProductAgentReq.getIsLimit() == null || LocalFunProductAgentReq.getIsLimit() == 0) {
                        LocalFunProductChannelOfflineAgentCustom.setLimitNum(LocalFunProductAgentReq.getLimitNum());
                    } else if (LocalFunProductAgentReq.getIsLimit() == 1) {
                        LocalFunProductChannelOfflineAgentCustom.setIsLimit(1);
                        LocalFunProductChannelOfflineAgentCustom.setLimitNum(LocalFunProductAgentReq.getLimitNum());
                    }
                    LocalFunProductChannelOfflineAgentCustom.setId(SnowflakeIdWorker.nextId());
                    localFunProductChannelOfflineAgentCustomMapper.insert(LocalFunProductChannelOfflineAgentCustom);
                    break;
                case 3:
                    saveOffLineChannel(LocalFunProductChannelOffline, LocalFunProductAgentReq.getOfflineAgentId(), offLineId, 3,ProductCenterEnum.AGENT_CUSTOM);
                    List<LocalFunProductChannelOfflineAgentCustomReq> LocalFunProductChannelOfflineAgentCustomReqList = LocalFunProductAgentReq.getScenicProductChannelOfflineAgentCustomReqList();
                    if (LocalFunProductChannelOfflineAgentCustomReqList != null) {
                        for (LocalFunProductChannelOfflineAgentCustomReq req1 : LocalFunProductChannelOfflineAgentCustomReqList) {
                            LocalFunProductChannelOfflineAgentCustom.setAgentId(req1.getAgentId());
                            LocalFunProductChannelOfflineAgentCustom.setAgentName(req1.getAgentName());
                            if (req1.getAdjustType() == 1) {
                                LocalFunProductChannelOfflineAgentCustom.setAdjustType(1);
                                LocalFunProductChannelOfflineAgentCustom.setAmount(req1.getAmount());
                            } else if (req1.getAdjustType() == 2) {
                                LocalFunProductChannelOfflineAgentCustom.setAdjustType(2);
                                LocalFunProductChannelOfflineAgentCustom.setPercent(req1.getPercent());
                            } else {
                                break;
                            }
                            if (req1.getIsLimit() == null || req1.getIsLimit() == 0) {
                                LocalFunProductChannelOfflineAgentCustom.setIsLimit(0);
                            } else  {
                                LocalFunProductChannelOfflineAgentCustom.setIsLimit(1);
                                LocalFunProductChannelOfflineAgentCustom.setLimitNum(req1.getLimitNum());
                            }
                            LocalFunProductChannelOfflineAgentCustom.setId(SnowflakeIdWorker.nextId());
                            localFunProductChannelOfflineAgentCustomMapper.insert(LocalFunProductChannelOfflineAgentCustom);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 新增/更新线下自营渠道
     * @param channelSaleReq    数据源
     * @param productId         产品ID
     * @param userId            用户ID
     * @param id                产品增幅策略ID
     */
    private void addOffLineSelCustom(ChannelSaleReq channelSaleReq, Long productId, Long userId, Long id) {
        LocalFunProductOfflineChannelReq localFunProductOfflineChannelReq = channelSaleReq.getLocalFunProductOfflineChannelReq();
        if (localFunProductOfflineChannelReq == null) {
            return;
        }

        //渠道權限
        Long officeId = SnowflakeIdWorker.nextId();
        LocalFunProductChannelOffline offline = LocalFunProductChannelOffline.builder().productId(productId)
                .channelType(ProductCenterEnum.SEL_CUSTOM_CHANNEL.getChannelCode())
                .createId(userId).isDeleted(0).strategyId(id).build();
        offline.setGmtCreate(LocalDateTime.now());

        //线下自营
        LocalFunProductChannelOfflineSelfCustom build = LocalFunProductChannelOfflineSelfCustom.builder().productId(productId)
                .createId(userId).isDeleted(0).build();
        build.setGmtCreate(LocalDateTime.now());


        switch (localFunProductOfflineChannelReq.getVisableType()) {
            case ProductCenterEnum.SEL_CUSTOM_FORBID:
                saveOffLineChannel(offline,localFunProductOfflineChannelReq.getOfflineSelfId(), officeId,ProductCenterEnum.SEL_CUSTOM_FORBID,ProductCenterEnum.SEL_CUSTOM);
                break;
            case ProductCenterEnum.ALL_DEPT_SALE:
                saveOffLineChannel(offline,localFunProductOfflineChannelReq.getOfflineSelfId(), officeId, ProductCenterEnum.ALL_DEPT_SALE,ProductCenterEnum.SEL_CUSTOM);

                //设置加幅类型：金额、百分比
                build.setCheckType(ProductCenterEnum.DEPT_CHOOSE);
                build.setId(localFunProductOfflineChannelReq.getRuleId());
                saveProductIncreaseStrategy(localFunProductOfflineChannelReq, build, officeId,localFunProductOfflineChannelReq.getAdjustType(), localFunProductOfflineChannelReq.getIsLimit() == ProductCenterEnum.IS_NOT_LIMIT.getChannelCode());
                break;
            case ProductCenterEnum.PERSONAL_SALE:
                saveOffLineChannel(offline, localFunProductOfflineChannelReq.getOfflineSelfId(), officeId, ProductCenterEnum.PERSONAL_SALE,ProductCenterEnum.SEL_CUSTOM);

                //设置指定部門/人員加幅
                List<LocalFunProductChannelOfflineSelfCustomReq> offlineSelfCustomReqList = localFunProductOfflineChannelReq.getChannelOfflineSelfCustomReqs();
                if(CollectionUtils.isNotEmpty(offlineSelfCustomReqList)){
                    for (LocalFunProductChannelOfflineSelfCustomReq customReq : offlineSelfCustomReqList) {
                        build.setCheckType(customReq.getCheckType());
                        build.setName(customReq.getName());
                        build.setRelationId(customReq.getRelationId());
                        build.setId(customReq.getRuleId());
                        localFunProductOfflineChannelReq.setAmount(customReq.getAmount());
                        localFunProductOfflineChannelReq.setLimitNum(customReq.getLimitNum());
                        localFunProductOfflineChannelReq.setPercent(customReq.getPercent());
                        saveProductIncreaseStrategy(localFunProductOfflineChannelReq, build, officeId, customReq.getAdjustType(), ProductCenterEnum.IS_NOT_LIMIT.getChannelCode().equals(customReq.getIsLimit()));
                    }
                }
                break;
            default:
                break;
        }
    }

    /**
     * 自營渠道
     * 刪除部門或按部門、人員加幅的信息
     * @param id
     * @param visableType
     */
    private void deleteHistoryChannelInfo(Long id, Integer visableType) {
        //權限選擇發誓變化： 1、刪除線下自營渠道配置的幅加表
        LocalFunProductChannelOffline oldChannelOffline = localFunProductChannelOfflineMapper.selectById(id);
        if(!oldChannelOffline.getVisableType().equals(visableType)){
            QueryWrapper<LocalFunProductChannelOfflineSelfCustom> wrapper2 = new QueryWrapper<>();
            wrapper2.lambda().eq(LocalFunProductChannelOfflineSelfCustom::getOfflineId,id);
            localFunProductChannelOfflineSelfCustomMapper.delete(wrapper2);
        }
    }


    /**
     * 代理商
     * 刪除部門或按部門、人員加幅的信息
     * @param id
     * @param visableType
     */
    private void deleteHistoryAgentChannelInfo(Long id, Integer visableType) {
        //權限選擇發誓變化： 1、刪除線下自營渠道配置的幅加表
        LocalFunProductChannelOffline oldChannelOffline = localFunProductChannelOfflineMapper.selectById(id);
        if(!oldChannelOffline.getVisableType().equals(visableType)){
            QueryWrapper<LocalFunProductChannelOfflineAgentCustom> wrapper2 = new QueryWrapper<>();
            wrapper2.lambda().eq(LocalFunProductChannelOfflineAgentCustom::getOfflineId,id);
            localFunProductChannelOfflineAgentCustomMapper.delete(wrapper2);
        }
    }

    /**
     * 保存产品加幅策略
     * @param localFunProductOfflineChannelReq
     * @param build
     * @param officeId
     * @param adjustType
     * @param equals
     */
    private void saveProductIncreaseStrategy(LocalFunProductOfflineChannelReq localFunProductOfflineChannelReq, LocalFunProductChannelOfflineSelfCustom build, Long officeId, Integer adjustType, boolean equals) {
        if (ProductCenterEnum.AMOUNT.getChannelCode().equals(adjustType)) {
            build.setAdjustType(ProductCenterEnum.AMOUNT.getChannelCode());
            build.setAmount(localFunProductOfflineChannelReq.getAmount());
        } else {
            build.setAdjustType(ProductCenterEnum.PERCENT.getChannelCode());
            build.setPercent(localFunProductOfflineChannelReq.getPercent());
        }
        if (equals) {
            build.setIsLimit(ProductCenterEnum.IS_NOT_LIMIT.getChannelCode());
        } else {
            build.setIsLimit(ProductCenterEnum.IS_LIMIT.getChannelCode());
            build.setLimitNum(localFunProductOfflineChannelReq.getLimitNum());
        }

        build.setId(SnowflakeIdWorker.nextId());
        build.setOfflineId(officeId);
        localFunProductChannelOfflineSelfCustomMapper.insert(build);

    }

    /**
     * 新增/更新權限渠道信息
     * @param offline           线下渠道信息
     * @param id
     * @param officeId
     * @param selCustomForbid   權限类型
     * @param channelType       渠道類型  1自營渠道 , 2代理商
     */
    private void saveOffLineChannel(LocalFunProductChannelOffline offline, Long id, Long officeId, int selCustomForbid,int channelType) {
        offline.setVisableType(selCustomForbid);
        offline.setId(officeId);
        localFunProductChannelOfflineMapper.insert(offline);
    }

    /**
     * 设置产品增幅策略有效期
     * @param productId                         产品ID
     * @param localFunProductSaleStrategyReq    请求入参
     * @param id                                产品增幅策略ID
     */
    private void addSaleStrategyValidDate(Long productId, LocalFunProductSaleStrategyReq localFunProductSaleStrategyReq, Long id) {
        List<LocalFunTimeDTO> time = localFunProductSaleStrategyReq.getTime();
        if (CollectionUtils.isNotEmpty(time)) {
            time.forEach(entity->{
                LocalFunProductSaleStrategyVaildDate saleStrategyValidDate = new LocalFunProductSaleStrategyVaildDate();
                saleStrategyValidDate.setProductId(productId);
                saleStrategyValidDate.setGmtCreate(LocalDateTime.now());
                saleStrategyValidDate.setTimeBegin(entity.getBeginTime());
                saleStrategyValidDate.setTimeEnd(entity.getEndTime());
                saleStrategyValidDate.setStrategyId(id);
                localFunProductSaleStrategyVaildDateMapper.insert(saleStrategyValidDate);
            });
        }
    }

    public static LocalDateTime getDateTimeOfTimestamp(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * 新增产品加幅策略
     * @param userId
     * @param productId
     * @param LocalFunProductSaleStrategyReq
     * @return
     */
    private Long addSaleStrategy(Long userId, Long productId, LocalFunProductSaleStrategyReq LocalFunProductSaleStrategyReq) {
        Long id = SnowflakeIdWorker.nextId();
        LocalFunProductSaleStrategy LocalFunProductSaleStrategy = new LocalFunProductSaleStrategy();
        LocalFunProductSaleStrategy.setId(id);
        LocalFunProductSaleStrategy.setCreateId(userId);
        LocalFunProductSaleStrategy.setIsDeleted(0);
        LocalFunProductSaleStrategy.setGmtCreate(LocalDateTime.now());
        LocalFunProductSaleStrategy.setProductId(productId);
        LocalFunProductSaleStrategy.setName(LocalFunProductSaleStrategyReq.getName());
        localFunProductSaleStrategyMapper.insert(LocalFunProductSaleStrategy);
        return id;
    }

    /**
     * 校验产品是否已配置该销售策略
     * @param productId
     * @return
     */
    private boolean strategyExistInDB(Long productId) {
        QueryWrapper<LocalFunProductSaleStrategy> LocalFunProductSaleStrategyQueryWrapper = new QueryWrapper<>();
        LocalFunProductSaleStrategyQueryWrapper.eq("product_id", productId);
        LocalFunProductSaleStrategyQueryWrapper.eq("is_deleted", 0);
        List<LocalFunProductSaleStrategy> localFunProductSaleStrategies = localFunProductSaleStrategyMapper.selectList(LocalFunProductSaleStrategyQueryWrapper);
        return CollectionUtils.isNotEmpty(localFunProductSaleStrategies);
    }

    /**
     * 增幅策略空数据校验
     * @param funProductIdList
     * @param strategyList
     * @return
     */
    private boolean checkStrategyEmpty(List<Long> funProductIdList, List<LocalFunProductSaleStrategyReq> strategyList) {
        return CollectionUtils.isEmpty(funProductIdList) || CollectionUtils.isEmpty(strategyList);
    }


    /**
     * 产品列表查询条件
     * @param req 查询条件请求参数值
     * @return    queryWrapper
     */
    private QueryWrapper<LocalFunProduct> queryParamCondition(LocalFunProductListReq req) {
        QueryWrapper<LocalFunProduct> queryWrapper = new QueryWrapper<>();
        //城市名称 模糊
        if (StringUtils.isNotBlank(req.getCityName())) {
            queryWrapper.lambda().like(LocalFunProduct::getCityName, req.getCityName());
        }
        //产品名称
        if (StringUtils.isNotBlank(req.getName())) {
            queryWrapper.lambda().like(LocalFunProduct::getName, req.getName());
        }
        //產品來源
        if (req.getSourceType() != null) {
            queryWrapper.lambda().eq(LocalFunProduct::getSourceType, req.getSourceType());
        }
        //供應商 模糊
        if (req.getSupplierId() != null) {
            queryWrapper.lambda().eq(LocalFunProduct::getSupplierId, req.getSupplierId());
        }
        if (StringUtils.isNotBlank(req.getSupplierName())) {
            queryWrapper.lambda().like(LocalFunProduct::getSupplierName, req.getSupplierName());
        }
        //產品類型
        if (null != req.getFunType() && req.getFunType() != 0L) {
            queryWrapper.lambda().eq(LocalFunProduct::getFunType, req.getFunType());
        }
        //上架狀態
        if (null != req.getStatus()) {
            queryWrapper.lambda().eq(LocalFunProduct::getStatus, req.getStatus());
        }
        //是否推薦
        if (null != req.getIsRecommend()) {
            queryWrapper.lambda().eq(LocalFunProduct::getIsRecommend, req.getIsRecommend());
        }
        return queryWrapper;
    }
}
